赛题
部分程序
主函数
/* USER CODE BEGIN 2 */
EEPROM_init();
LED_init();
KEY_init();
LCD_Init();
USER_DATA_init(); //数据初始化
TASK_TIMES_init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
KEY_function();
ADC_function();
UART_function();
LED_function();
LCD_function();
}
/* USER CODE END 3 */
按键功能函数、
u8 KEY_SCAN(void)
{
u8 val,key;
static u8 com;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET) val=1;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET) val=2;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET) val=3;
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET) val=4;
else val=0;
key=val&(val^com);
com=val;
return key;
}
void KEY_function(void)
{
u8 key;
if(get_time_task(TASK_TIMES.KEY_TIME)==0)
{
TASK_TIMES.KEY_TIME=get_time()+KEY_time;
key=KEY_SCAN();
if(key==1) //切换界面
{
if(!LCD_display) //数据显示界面
{
Threshold_temporary[0]=Threshold[0]; //获取阈值数据
Threshold_temporary[1]=Threshold[1];
Threshold_temporary[2]=Threshold[2];
flag_set=0; //每次进入设置阈值界面时,从阈值1开始
sprintf((char *)LCD_Line2_buf," Parameter Setup ");
sprintf((char *)LCD_Line3_buf," Threshold 1: %2dcm ",Threshold_temporary[0]);
sprintf((char *)LCD_Line4_buf," Threshold 2: %2dcm ",Threshold_temporary[1]);
sprintf((char *)LCD_Line5_buf," Threshold 3: %2dcm ",Threshold_temporary[2]);
}
else //阈值设置界面
{
Threshold[0]=Threshold_temporary[0]; //保存阈值数据
Threshold[1]=Threshold_temporary[1];
Threshold[2]=Threshold_temporary[2];
//保存到E2PROM
EEPROM[0]=123;
EEPROM[1]=Threshold[0];
EEPROM[2]=Threshold[1];
EEPROM[3]=Threshold[2];
EEPROM_write(0,EEPROM,4);
sprintf((char *)LCD_Line2_buf," Liquid Level ");
sprintf((char *)LCD_Line3_buf," Height: 50cm ");
sprintf((char *)LCD_Line4_buf," ADC : 1.65V ");
sprintf((char *)LCD_Line5_buf," Level : 1 ");
}
LCD_DisplayStringLine(Line2,LCD_Line2_buf);
LCD_display=!LCD_display;
}
else if(key==2) //切换选择
{
if(LCD_display) //仅在阈值设置界面下有效
{
if(++flag_set==3) {flag_set=0;} //切换被选中的阈值
}
}
else if(key==3) //加
{
if(LCD_display) //仅在阈值设置界面下有效
{
if(flag_set==2) {if(Threshold_temporary[flag_set]!=95) {Threshold_temporary[flag_set]+=5;}} //最大阈值95
else
{
if(Threshold_temporary[flag_set+1]-Threshold_temporary[flag_set]>5) //阈值不能大于等于上级阈值
{ Threshold_temporary[flag_set]+=5; }
}
}
}
else if(key==4) //减
{
if(LCD_display) //仅在阈值设置界面下有效
{
if(flag_set==0) {if(Threshold_temporary[flag_set]!=5) {Threshold_temporary[flag_set]-=5;}} //最小阈值5
else
{
if(Threshold_temporary[flag_set]-Threshold_temporary[flag_set-1]>5) //阈值不能小于等于下级阈值
{ Threshold_temporary[flag_set]-=5; }
}
}
}
}
}
ADC功能函数
void ADC_function(void)
{
u8 a;
u32 data=0;
if(get_time_task(TASK_TIMES.ADC_TIME)==0)
{
TASK_TIMES.ADC_TIME=get_time()+ADC_time;
HAL_ADC_Stop_DMA(&hadc2);
for(a=0;a<50;a++)
{
data+=ADC_buf[a];
}
HAL_ADC_Start_DMA(&hadc2,(u32 *)&ADC_buf,50); //使能ADC DMA转换
data/=50; //ADC近50次均值
ADC=data*330/4095; //传感器输出 放大100倍,保留2位小数
Height=ADC/3.3; //液位高度 K=100/3.3 Height=Vr37*K=((ADC/100)*100)/3.3 四舍五入
if(Height<=Threshold[0]) Level=0;
else if(Height<=Threshold[1]) Level=1;
else if(Height<=Threshold[2]) Level=2;
else Level=3;
if((flag_Level&0X03)!=Level) //液位等级改变
{
if((flag_Level&0X03)>Level) //下降
{ sprintf((char *)UART1_TX_buf,"A:H%d+L%d+D\r\n ",Height,Level); }
else //上升
{ sprintf((char *)UART1_TX_buf,"A:H%d+L%d+U\r\n ",Height,Level); }
HAL_UART_Transmit_DMA(&huart1,UART1_TX_buf,14);
flag_Level=(Level&0x03); //保存本次液位等级
flag_Level|=0x80; //液位等级改变标志位置1
}
}
}
串口功能函数
void UART_function(void)
{
u8 len;
if(flag_UART1_over)
{
flag_UART1_over=0;
if(UART1_RX_num==1) //判断是的正确指令长度
{
flag_uart=1;
if(UART1_RX_buf[0]=='C') //返回当前液位高度和液位等级
{
sprintf((char *)UART1_TX_buf,"C:H%d+L%d\r\n ",Height,Level);
len=12;
}
else if(UART1_RX_buf[0]=='S') //返回当前设定三个阈值
{
sprintf((char *)UART1_TX_buf,"S:TL%d+TM%d+TH%d\r\n ",Threshold[0],Threshold[1],Threshold[2]);
len=18;
}
else flag_uart=0;
if(flag_uart) HAL_UART_Transmit_DMA(&huart1,UART1_TX_buf,len);
}
HAL_UART_Receive_DMA(&huart1,UART1_RX_buf,UART1_TX_LEN);
}
}
LED功能函数
void LED_function(void)
{
static u8 LED_state_last=0XFF;
static u8 time_num=0;
static u8 flag_LD2=0; //bit 7 LD2闪烁标志位 6:4 保留 3:0 闪烁次数
static u8 flag_LD3=0; //bit 7 LD2闪烁标志位 6:4 保留 3:0 闪烁次数
if(get_time_task(TASK_TIMES.LED_TIME)==0)
{
TASK_TIMES.LED_TIME=get_time()+LED_time;
if(++time_num%5==0) {LED_state^=(1<<0);} //运行状态指示灯,1秒间隔闪烁
if(flag_Level&0x80) //液位等级发生改变,LD2以0.2秒间隔闪烁5次
{
flag_Level&=0X7F; //液位等级发生改变标志位清零
flag_LD2&=0xF0; //闪烁次数清零
flag_LD2|=0x80; //闪烁标志位置1
}
if(flag_uart)
{
flag_uart=0;
flag_LD3&=0xF0; //闪烁次数清零
flag_LD3|=0x80; //闪烁标志位置1
}
if(flag_LD2&0x80)
{
flag_LD2++; //闪烁次数加1
if((flag_LD2&0x0F)==10) {flag_LD2&=0x70;}
LED_state^=(1<<1);
}
else {LED_state|=0x02;}
if(flag_LD3&0x80)
{
flag_LD3++; //闪烁次数加1
if((flag_LD3&0x0F)==10) {flag_LD3&=0x70;}
LED_state^=(1<<2);
}
else {LED_state|=0x04;}
if(LED_state_last!=LED_state) //LED状态,发生改变
{
LED_state_last=LED_state;
LED_write(LED_state);
}
}
}
LCD功能函数
void LCD_function(void)
{
if(get_time_task(TASK_TIMES.LCD_TIME)==0)
{
TASK_TIMES.LCD_TIME=get_time()+LCD_time;
if(!LCD_display) //数据显示界面
{
LCD_Line3_buf[9]=Height/10+48;LCD_Line3_buf[10]=Height%10+48;
LCD_Line4_buf[9]=ADC/100+48;LCD_Line4_buf[11]=ADC/10%10+48;LCD_Line4_buf[12]=ADC%10+48;
LCD_Line5_buf[9]=Level+48;
}
else //阈值设置界面
{
LCD_Line3_buf[14]=Threshold_temporary[0]/10+48;LCD_Line3_buf[15]=Threshold_temporary[0]%10+48;
LCD_Line4_buf[14]=Threshold_temporary[1]/10+48;LCD_Line4_buf[15]=Threshold_temporary[1]%10+48;
LCD_Line5_buf[14]=Threshold_temporary[2]/10+48;LCD_Line5_buf[15]=Threshold_temporary[2]%10+48;
}
//阈值设置界面下,被选中的高亮
if(LCD_display&&(flag_set==0)) {LCD_SetTextColor(Green);LCD_DisplayStringLine(Line3,LCD_Line3_buf);LCD_SetTextColor(White);}
else {LCD_DisplayStringLine(Line3,LCD_Line3_buf);}
if(LCD_display&&(flag_set==1)) {LCD_SetTextColor(Green);LCD_DisplayStringLine(Line4,LCD_Line4_buf);LCD_SetTextColor(White);}
else {LCD_DisplayStringLine(Line4,LCD_Line4_buf);}
if(LCD_display&&(flag_set==2)) {LCD_SetTextColor(Green);LCD_DisplayStringLine(Line5,LCD_Line5_buf);LCD_SetTextColor(White);}
else {LCD_DisplayStringLine(Line5,LCD_Line5_buf);}
}
}
完整程序下载
下载链接:
链接:https://pan.baidu.com/s/1LMECSy3GuABduu42YUJdSQ
提取码:qy2o