个人做题记录,仅供参考
main.c
#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"
#include "key.h"
#include "lcd.h"
#include "rtc.h"
#include "adc.h"
#include "led.h"
#include "usart.h"
uint8_t Lcd_flag =0;
uint8_t Sent_OK =0;
uint8_t Led_status = 0;
uint8_t hour = 0;
uint8_t min = 0;
uint8_t sec = 0;
uint8_t Time_200ms = 0;
uint8_t Lcd_light = 0;
char Rx_Buf[10] = {0};
int SetTime_Buf[3] = {0,0,0};
unsigned char Buf[20] = {0};
float ADC_Val = 0;
float k = 0.1;
uint8_t RXOVER = 0;
u32 TimingDelay = 0;
void Delay_Ms(u32 nTime);
void Key_Proc(int *p);
void Lcd_Proc(void);
void RTC_Proc(void);
void Led_Proc(void);
void USART2_Proc(void);
void highlight(uint8_t *str,uint8_t pos);
int main(){
SysTick_Config(SystemCoreClock/1000);
Delay_Ms(200);
STM3210B_LCD_Init();
KEY_Init();
rtc_init();Time_Adjust(23,59,55);
ADC1_Init();
LED_Init();
USART2_Init(9600);
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
while(1){
ADC_Val = (float)(ADC1_Conv() * 3.3 / 4096);
Key_Proc(SetTime_Buf);
Led_Proc();
Lcd_Proc();
Time_Refresh();
USART2_Proc();
}
}
/*******************************************************************************
* 函数名 :Key_Proc
* 输入值 :整型指针变量p
* 返回值 :无
* 作者 :Moqim Flourite.
* 时间 :2022年3月30日
* 功能描述:按键设置
* 备注 :“B1”按键设定为“功能”按键,打开/关闭指示灯闪烁报警功能,默认为打开状态;
“B2”按键设定为“设置”按键,设置设备自动上报电压时间,
按下B2后,LCD显示界面如图2所示,
此时通过按键B3切换选择时、分、秒,通过按键B4进行调整,
完成调整后,按下B2按键,更新自动上报时间,并返回图1所示的LCD显示界面。
*******************************************************************************/
void Key_Proc(int *p){
static uint8_t Key_Val,Key_Down,Key_Old;
static uint8_t i = 0;
Key_Val = KEY_Scan();
Key_Down = Key_Val & (Key_Val ^ Key_Old);
Key_Old = Key_Val;
switch(Key_Down){
case 1:
Led_status = !Led_status;break;
case 2:
if(Lcd_flag == 0){
i = 0;
}
Lcd_flag = !Lcd_flag;
break;
case 3:
if(Lcd_flag == 1){
if(++ i == 3)i = 0;
}break;
case 4:
if(Lcd_flag == 1){
p[i]++;
}break;
default:break;
}
Lcd_light = i;
}
/*******************************************************************************
* 函数名 :Lcd_Proc
* 输入值 :无
* 返回值 :无
* 作者 :Moqim Flourite.
* 时间 :2022年4月2日
* 功能描述:按键设置
* 备注 :功能页面:显示电位器输出电压V1(保留小数点后两位有效数字)、k值、
指示灯闪烁报警功能状态和系统时间;
显示页面:显示“Setting”与上报时间的时分秒;设置时间时高亮设置部分;
*******************************************************************************/
void Lcd_Proc(void){
if(Lcd_flag == 0){//显示模式
sprintf((char*)Buf," V1:%.2fV ",ADC_Val);
LCD_DisplayStringLine(Line1,Buf);
memset(Buf,0,(20 * sizeof(unsigned char)));
sprintf((char*)Buf," k:%.1f ",k);
LCD_DisplayStringLine(Line3,Buf);
memset(Buf,0,(20 * sizeof(unsigned char)));
if(Led_status == 0)LCD_DisplayStringLine(Line5," LED:ON ");
else LCD_DisplayStringLine(Line5," LED:OFF ");
sprintf((char*)Buf," T:%02d-%02d-%02d ",hour,min,sec);
LCD_DisplayStringLine(Line7,Buf);
memset(Buf,0,(20*sizeof(unsigned char)));
LCD_DisplayStringLine(Line9," 1");
}
else{
LCD_DisplayStringLine(Line1," Setting ");
sprintf((char*)Buf," %02d-%02d-%02d ",SetTime_Buf[0],SetTime_Buf[1],SetTime_Buf[2]);
switch(Lcd_light){
case 0:highlight(Buf,6);break;
case 1:highlight(Buf,9);break;
case 2:highlight(Buf,12);break;
}
LCD_SetTextColor(White);
memset(Buf,0,(20 * sizeof(unsigned char)));
LCD_DisplayStringLine(Line9," 2");
LCD_ClearLine(Line5);
LCD_ClearLine(Line7);
}
}
/*******************************************************************************
* 函数名 :Led_Proc
* 输入值 :无
* 返回值 :无
* 作者 :Moqim Flourite.
* 时间 :2022年4月2日
* 功能描述:LED显示
* 备注 :当V1>VDD*k时,指示灯LD1以0.2秒为间隔闪烁,闪烁功能可以通过按键关闭,但上电默认开启;
*******************************************************************************/
void Led_Proc(void){
static uint8_t led = 0;
if(Led_status == 0){
if(ADC_Val > (k * 3.3)){
if(Time_200ms == 1){
Time_200ms = 0;
led = 0x01;
}
else led = 0;
}
else led = 0;
}
else{
led = 0;
}
LED_Disp(led);
}
/*******************************************************************************
* 函数名 :USART2_IRQHandler
* 输入值 :无
* 返回值 :无
* 作者 :Moqim Flourite.
* 时间 :2022年4月2日
* 功能描述:串口2中断服务函数
* 备注 :接收数据,当接收到换行符‘\n’时,停止接收,并开启检测标志位;
*******************************************************************************/
void USART2_IRQHandler(void){
static char temp;
static int i = 0;
if(USART_GetITStatus(USART2,USART_IT_RXNE)){
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
temp = USART_ReceiveData(USART2);
if(temp == 0x0a){
i = 0;
RXOVER = 1;
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//关闭中断
}
else{
Rx_Buf[i] = temp;
i++;
}
}
}
/*******************************************************************************
* 函数名 :USART2_Proc
* 输入值 :无
* 返回值 :无
* 作者 :Moqim Flourite.
* 时间 :2022年4月2日
* 功能描述:串口2发送函数
* 备注 :1:检测是否接收到正确字符串,是就发送"OK";
2:当时间到达设置发送时间时,按模版上报电压值;
这个检测的写的有点low,但是能用就行hhhh.
*******************************************************************************/
void USART2_Proc(void){
static uint8_t Sent_Buf[20] = {0};
if(RXOVER == 1){
RXOVER = 0;
if(Rx_Buf[0] == 'k'){
if(Rx_Buf[1] == '0'){
if(Rx_Buf[2] == '.'){
if((Rx_Buf[3] > 0x30) && (Rx_Buf[3] < 0x3a) ){
Sent_OK = 1;
k = (float)(Rx_Buf[3] - 48) / 10;
}
}
}
}
memset(Rx_Buf,0,(10 * sizeof(char)));
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
if(Sent_OK == 1){
Sent_OK = 0;
USART_SendString(USART2, "ok\n");
}
if(SetTime_Buf[0] == hour && SetTime_Buf[1] == min && SetTime_Buf[2] == sec){
sprintf((char*)Sent_Buf,"%.2f+%.1f+%02d%02d%02d\n",ADC_Val,k,hour,min,sec);
USART_SendString(USART2,Sent_Buf);
Delay_Ms(1000);
memset(Sent_Buf,0,(20 * sizeof(uint8_t)));
}
}
/*******************************************************************************
* 函数名 :highlight
* 输入值 :uint8_t *str,uint8_t pos
* 返回值 :无
* 作者 :Moqim Flourite.
* 时间 :2022年4月3日
* 功能描述:lcd高亮函数
* 备注 :使得pos位与pos+1位的字符高亮(变字体颜色);
*******************************************************************************/
void highlight(uint8_t *str,uint8_t pos)
{
int i = 0;
for(i = 0; i <= 19; i++)
{
if(i != pos && i != (pos + 1))
LCD_DisplayChar(Line3,(320 - (16 * i)),str[i]);
}
LCD_SetTextColor(Red);
LCD_DisplayChar(Line3,(320 - (16 * pos)),str[pos]);
LCD_DisplayChar(Line3,(320 - (16 * (pos + 1))),str[pos+1]);
// LCD_SetTextColor(White);
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
//stm32f10x_it.c
extern u32 TimingDelay;
extern uint8_t Time_200ms;
void SysTick_Handler(void)
{
static int i = 0;
TimingDelay --;
if(++ i == 200){
i = 0;
Time_200ms = 1;
}
}
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
if(RTC_GetCounter()==86400)//24 * 3600
{
RTC_SetCounter(0x0);
}
/* Clear Interrupt pending bit */
RTC_ClearITPendingBit(RTC_FLAG_SEC);
}
}
问题:
1、if一定要配套个else,不然会保持上一次的动作。
2、注意参数影响值的个数(如highlight函数里if的条件语句)。
3、sprintf和memset不熟练,要多记几遍。
4、串口检测太low了,要去学别人的方法。