900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 【学习】蓝桥杯嵌入式:第七届预赛试题—液位检测告警系统

【学习】蓝桥杯嵌入式:第七届预赛试题—液位检测告警系统

时间:2020-07-25 23:16:12

相关推荐

【学习】蓝桥杯嵌入式:第七届预赛试题—液位检测告警系统

前言

个人认为,比赛前做大量的练习,是非常必要的。我只放了一部分主要代码,思路还是挺清晰的。给大家创造的空间。如果想要源码,最下面也有途径。下面上干货。

一、题目重述

功能描述

二、系统设计分析

思路:题目所给任务,进行逐级分析,分块实现。(下手角度因人而异)

首先,我考虑的是先实现功能三,先实现按键控制功能切换。在按键切换功能完成的基础上,分别按照题目要求,进完善每个功能。我选择的是先从简单的入手。

程序框架如下:

void KEY_Cmd_Judge(void){key_cmd_flag = KEY_Read();if(key_cmd_flag == 1) {B1_Cmd_Processing();//按键1://按键 B1 为设置键,按下后进入阈值设置显示界面,再次按下时保存设置结果到 EEPROM,并返回液位检测显示界面。}else if(key_cmd_flag == 2){B2_Cmd_Processing();//按键2}else if(key_cmd_flag == 3){B3_Cmd_Processing(); //按键3}else if(key_cmd_flag == 4){B4_Cmd_Processing(); //按键4}}

2、按键 B1

实现切换阈值设置显示界面,和将设置阈值存入 EEPROM,并返回液位检测显示界面。

static void B1_Cmd_Processing(void){cmd1_flag++;//按键 B1 为设置键,按下后进入阈值设置显示界面,//再次按下时保存设置结果到 EEPROM,并返回液位检测显示界面if(cmd1_flag%2 == 1){//阈值显示设置界面Threshold_Display();}if(cmd1_flag%2 == 0){EEPROM_Write(); //写入数据LED_State(7); //状态显示Liquid_Display();}}

2、按键 B2

切换键,切换选择 3 个阈值,被选择的阈值突出显示。

static void B2_Cmd_Processing(void){//按键 B2 为切换键,切换选择 3 个阈值,被选择的阈值突出显示。//这个在设置阈值的时候,有所体现。cmd2_flag++;LCD_SetTextColor(Blue);Threshold_Display();if(cmd2_flag == 1){LED_State(4);High1 = threshold;}else if(cmd2_flag == 2){LED_State(5);High2 = threshold;}else if(cmd2_flag == 3){LED_State(6);High3 = threshold;}else if(cmd2_flag == 4){cmd2_flag = 0;LED_State(8);}}

3、按键 B3

阈值加,每按一次,阈值增加 5cm,增加到 95cm 为止。

static void B3_Cmd_Processing(void){threshold += 5;if(threshold > 95)threshold = 95;//限定一定小于95if(cmd2_flag == 1){High1 = threshold;}else if(cmd2_flag == 2){High2 = threshold;}else if(cmd2_flag == 3){High3 = threshold;}if(cmd1_flag%2 == 1) Threshold_Display();}

4、按键 B4

为加键,每按一次,阈值增减 5cm,增加到 5cm 为止。

static void B4_Cmd_Processing(void){threshold -= 5;if(threshold < 5)threshold = 5; //限定一定大于5if(cmd2_flag == 1){High1 = threshold;}else if(cmd2_flag == 2){High2 = threshold;}else if(cmd2_flag == 3){High3 = threshold;}if(cmd1_flag%2 == 1) Threshold_Display();}

5、子函数:一些框架内功能的实现

LED状态显示函数

static void LED_State(uint8_t LED){switch(LED){case 1:{LED_Control(LED1,1);LED_Control(LED2|LED3|LED4|LED5|LED6|LED7,0);break;}case 2:{LED_Control(LED2,1);LED_Control(LED1|LED3|LED4|LED5|LED6|LED7,0);break;}case 3:{LED_Control(LED3,1);LED_Control(LED2|LED1|LED4|LED5|LED6|LED7,0);break;}case 4:{LED_Control(LED4,1);LED_Control(LED2|LED1|LED3|LED5|LED6|LED7,0);break;}case 5:{LED_Control(LED5,1);LED_Control(LED2|LED1|LED3|LED4|LED6|LED7,0);break;}case 6:{LED_Control(LED6,1);LED_Control(LED2|LED1|LED3|LED5|LED4|LED7,0);break;}case 7:{LED_Control(LED7,1);LED_Control(LED2|LED1|LED3|LED5|LED6|LED4,0);break;}case 8:{LED_Control(LED2|LED1|LED3|LED5|LED6|LED4|LED7,0);break;}default:{break;}}}

液面显示、阈值突出显示功能

void Liquid_Display(void){//正常显示页面信息LCD_Clear(White);LCD_SetTextColor(Blue);VR_37 = (float)ADCConvertedValue*3.3/4096;High = Get_High(VR_37);Level = Get_Level(High);LCD_DisplayStringLine(Line1," Liquid Level ");sprintf((char*)Txt_Threshold," Height:%dcm ",High);LCD_DisplayStringLine(Line5,Txt_Threshold);sprintf((char*)Txt_Threshold," VR37: %1.2fv ",VR_37);LCD_DisplayStringLine(Line6,Txt_Threshold);sprintf((char*)Txt_Threshold," Level: %d ",Level);LCD_DisplayStringLine(Line7,Txt_Threshold);}void Threshold_Display(void){//阈值重点显示LCD_Clear(White);if((cmd2_flag == 0)||(cmd2_flag == 4)){LCD_SetTextColor(Blue);LCD_DisplayStringLine(Line1," Threshold Setup ");sprintf((char*)Txt_Threshold," Threshold1: %2dcm ",High1);LCD_DisplayStringLine(Line5,Txt_Threshold);sprintf((char*)Txt_Threshold," Threshold2: %2dcm ",High2);LCD_DisplayStringLine(Line6,Txt_Threshold);sprintf((char*)Txt_Threshold," Threshold3: %2dcm ",High3);LCD_DisplayStringLine(Line7,Txt_Threshold);}else if(cmd2_flag == 1){LCD_SetTextColor(Blue);sprintf((char*)Txt_Threshold," threshold: %2dcm ",threshold);LCD_DisplayStringLine(Line9,Txt_Threshold);LCD_DisplayStringLine(Line1," Threshold Setup ");LCD_SetTextColor(Red);sprintf((char*)Txt_Threshold," Threshold1: %2dcm ",High1);LCD_DisplayStringLine(Line5,Txt_Threshold);LCD_SetTextColor(Blue);sprintf((char*)Txt_Threshold," Threshold2: %2dcm ",High2);LCD_DisplayStringLine(Line6,Txt_Threshold);sprintf((char*)Txt_Threshold," Threshold3: %2dcm ",High3);LCD_DisplayStringLine(Line7,Txt_Threshold);}else if(cmd2_flag == 2){LCD_SetTextColor(Blue);sprintf((char*)Txt_Threshold," threshold: %2dcm ",threshold);LCD_DisplayStringLine(Line9,Txt_Threshold);LCD_DisplayStringLine(Line1," Threshold Setup ");sprintf((char*)Txt_Threshold," Threshold1: %2dcm ",High1);LCD_DisplayStringLine(Line5,Txt_Threshold);LCD_SetTextColor(Red);sprintf((char*)Txt_Threshold," Threshold2: %2dcm ",High2);LCD_DisplayStringLine(Line6,Txt_Threshold);LCD_SetTextColor(Blue);sprintf((char*)Txt_Threshold," Threshold3: %2dcm ",High3);LCD_DisplayStringLine(Line7,Txt_Threshold);}else if(cmd2_flag == 3){LCD_SetTextColor(Blue);sprintf((char*)Txt_Threshold," threshold: %2dcm ",threshold);LCD_DisplayStringLine(Line9,Txt_Threshold);LCD_DisplayStringLine(Line1," Threshold Setup ");sprintf((char*)Txt_Threshold," Threshold1: %2dcm ",High1);LCD_DisplayStringLine(Line5,Txt_Threshold);sprintf((char*)Txt_Threshold," Threshold2: %2dcm ",High2);LCD_DisplayStringLine(Line6,Txt_Threshold);LCD_SetTextColor(Red);sprintf((char*)Txt_Threshold," Threshold3: %2dcm ",High3);LCD_DisplayStringLine(Line7,Txt_Threshold);}}

液面高度转换,Level判断,EEPROM存储

/* 液压相关 */float Get_High(float V) //获取页面高度{return (V/3.3)*100;}static uint8_t Get_Level(uint16_t H) //获取页面高度{uint8_t L_temp = 0;if(H<=High1){L_temp = 1;}else if((H > High1) && (H <= High2)){L_temp =2;}else if((H > High2) && (H <= High3)){L_temp =3;}else if(H>High3){L_temp = 4;}return L_temp;}void EEPROM_Read(void){//存储EEPROM数据 选前三个内存地址 存入 easyHigh1 = Byte_Read(0x00);High2 = Byte_Read(0x02); //需要加延时么? 待测High3 = Byte_Read(0x04);}void EEPROM_Write(void){//存储EEPROM数据 选前三个内存地址 存入 easyByte_Write(0x00,High1);Delay_Soft(0xffff);Byte_Write(0x02,High2); //需要加延时时间 自行调试Delay_Soft(0xffff);Byte_Write(0x04,High3);}

到此前三个任务已经完成

下面功能4:

串口查询与输出功能:中断实现

void USART2_IRQHandler(void){if(USART_GetITStatus(USART_PORT, USART_IT_RXNE) != RESET){Usart_temp = getchar();Usart_flag = 1;if(Usart_temp == 'C'){printf("C:\n High:%d Level:%d\r\n",High,Level);}if(Usart_temp == 'S'){printf("S:\n Threshold1:%d cm\n Threshold2:%d cm\n Threshold3:%d cm\n\r\n\n",High1,High2,High3);}}USART_ClearITPendingBit(USART_PORT,USART_IT_RXNE);}

功能5

状态显示

void SysTick_Handler(void){Time_Handler_Display++;Time_Handler_LED2++;Time_Handler_LED3++;if(Time_Handler_Display == Liquid_Display_Time){Time_Handler_Display = 0;if(cmd1_flag%2 == 0){LED_Toggle(1);Liquid_Display();}}if(Time_Handler_LED2 == LED2_Toggle_Time) //不用每次都判断 0.2s判断一次就够了{Time_Handler_LED2 = 0;if(Level != Level_temp){LED_Toggle(2);Level_temp_i++;Level_Change();}}if(Time_Handler_LED3 == LED3_Toggle_Time) //不用每次都判断 0.2s判断一次就够了{Time_Handler_LED3 = 0;if(Usart_flag == 1){LED_Toggle(3);Usart_i++;if(Usart_i == 10) {Usart_flag = 0;Usart_i = 0;}}}if(TimeDelay_Ms != 0){TimeDelay_Ms--;}}void USART2_IRQHandler(void){if(USART_GetITStatus(USART_PORT, USART_IT_RXNE) != RESET){Usart_temp = getchar();Usart_flag = 1;if(Usart_temp == 'C'){printf("C_cmd:\n High:%d Level:%d\r\n",High,Level);}if(Usart_temp == 'S'){printf("S_cmd:\n Threshold1:%d cm\n Threshold2:%d cm\n Threshold3:%d cm\n\r\n\n",High1,High2,High3);}}USART_ClearITPendingBit(USART_PORT,USART_IT_RXNE);}

main.c

int main(void){ALL_Init();while(1){KEY_Cmd_Judge();}}

三、测试

led也是按照预期闪烁

四、总结:

主要用到的模块:ADC、EEPROM、USART、GPIO、Systick、LCD、KEY.

先整体搭建程序框架、逐步完善。关于LCD的显示倒没什么,主要是中间有一些细节,什么时候显示什么界面,需要底层判断,然后判断flag,然后就是ADC和串口的配置,需要熟练掌握。EEPROM注意在写入的时候,加延时,否则会出错。

工程源码:

链接:/s/13XMY5Wa8uR1CaAP-cZX1dQ 提取码:7a0n

方便的话,可以一键三连鼓励一下哦

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。