题目分析
模块配置、编写
有了第十三届真题的经验,根据题目所给硬件框图,先在cube中创建工程,配置相应的GPIO和定时器,完成pwm输出、LED指示、LCD显示、按键、串口通信五个模块代码编写。
TIM4作按键模块定时器
TIM17作信号输出模块定时器
串口
按键模块:.c
#include "key.h"
struct KEY_STA key_sta[4] = {0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //定时器溢出中断回调函数
{
if(htim->Instance == TIM4)
{
key_sta[0].value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key_sta[1].value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key_sta[2].value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key_sta[3].value = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
}
for(uint8_t i = 0;i<4;i++) //三个状态消抖
{
switch(key_sta[i].step)
{
case 0:
{
if(key_sta[i].value == 0)
{
key_sta[i].step ++;
}
}
break;
case 1:
{
if(key_sta[i].value == 0)
{
key_sta[i].step ++;
key_sta[i].flag = 1;
}
else
{
key_sta[i].step = 0;
}
}
break;
case 2:
{
if(key_sta[i].value == 1)
{
key_sta[i].step = 0;
}
}
break;
}
}
}
void key_pro() //按键功能实现函数
{
if(key_sta[0].flag == 1)
{
led_pro(0x80);
key_sta[0].flag = 0;
}
if(key_sta[1].flag == 1)
{
key_sta[1].flag = 0;
}
if(key_sta[2].flag == 1)
{
key_sta[2].flag = 0;
}
if(key_sta[3].flag == 1)
{
key_sta[3].flag = 0;
}
}
led模块:
#include "key.h"
void led_pro(uint8_t cho)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,cho << 8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
lcd显示模块:
#include "dis.h"
uint8_t view = 0;
uint8_t text[30] = {0};
void dis_pro() //显示界面函数
{
if(view == 0) //界面一
{
sprintf((char *)text," D a t a");
LCD_DisplayStringLine(Line1,text);
}
if(view == 1) //界面二
{
sprintf((char *)text," P a r a");
LCD_DisplayStringLine(Line1,text);
}
}
串口通信模块:
#include "n_uart.h"
uint8_t Dat = 0;
uint8_t Re_dat[30] = {0};
uint8_t pointer = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口接收中断回调函数
{
Re_dat[pointer++] = Dat;
HAL_UART_Receive_IT(huart, &Dat, 1);
}
具体功能实现
看过题目要求后,发现最复杂的就是串口模块的功能:
void uart_pro() //串口功能实现函数
{
if(pointer == 22)
{
sscanf((char *)Re_dat,"%4s:%4s:%12s",Type,Num,Time);
if(0==strcmp((char *)Type,(char *)Type_C))
C_Num++;
if(0==strcmp((char *)Type,(char *)Type_V))
V_Num++;
for(uint8_t i = 0;i<8;i++)
{
if((0 == strcmp((char *)Type,(char *)tc[i].type)) && (0 == strcmp((char *)Num,(char *)tc[i].num))) //判断是否已经停入
{
stay = ((Time[6]-'0')*10+(Time[7]-'0'))-((tc[i].time[6]-'0')*10+(tc[i].time[7]-'0')); //计算停车时长
if(((Time[8]-'0')*10+(Time[9]-'0'))-((tc[i].time[8]-'0')*10+(tc[i].time[9]-'0'))>0)
stay++;
if(0==strcmp((char *)Type,(char *)Type_C)) //判断是哪种停车类型
{
C_Num -= 2; //车开出来
mon = stay * mon_c; //消费
}
if(0==strcmp((char *)Type,(char *)Type_V))
{
V_Num -= 2 ;
mon = stay * mon_v;
}
uint8_t temp[30] = {0};
sprintf((char *)temp,"%4s:%4s:%2d:%.2f",Type,Num,stay,mon);
HAL_UART_Transmit(&huart1,temp,strlen((char *)temp),50); //反馈消费信息
memset(tc[i].type,0,5); //车位信息清零
memset(tc[i].num,0,5);
memset(tc[i].time,0,13);
break;
}
else //如果没有停过,就将车停进去
{
if(S_Num > 0) //如果还有空位置
{
strcpy((char *)tc[i].type,(char *)Type);
strcpy((char *)tc[i].num,(char *)Num);
strcpy((char *)tc[i].time,(char *)Time);
break;
}
}
}
}
else //如果收到的字符串不正确
{
uint8_t temp[30] = {0};
sprintf((char *)temp,"ERROR");
HAL_UART_Transmit(&huart1,temp,strlen((char *)temp),50);
}
pointer = 0;
memset(Re_dat,0,30);
}
按键、信号输出模块:
void key_pro() //按键功能实现函数
{
if(key_sta[0].flag == 1) //切换界面
{
view ++;
if(view > 1)
view = 0;
LCD_Clear(Black);
key_sta[0].flag = 0;
}
if(key_sta[1].flag == 1) //调整费率
{
mon_c += 0.5;
mon_v += 0.5;
key_sta[1].flag = 0;
}
if(key_sta[2].flag == 1)
{
mon_c -= 0.5;
mon_v -= 0.5;
key_sta[2].flag = 0;
}
if(key_sta[3].flag == 1) //信号设置
{
if(frq == 0)
{
__HAL_TIM_SET_AUTORELOAD(&htim17, 1999);
__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, 399);
}
else
{
__HAL_TIM_SET_AUTORELOAD(&htim17, 1999);
__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, 0);
}
key_sta[3].flag = 0;
}
}
LCD显示
void dis_pro() //显示界面函数
{
if(view == 0) //界面一
{
sprintf((char *)text," D a t a");
LCD_DisplayStringLine(Line1,text);
sprintf((char *)text," C N B R:%d",C_Num);
LCD_DisplayStringLine(Line4,text);
sprintf((char *)text," V N B R:%d",V_Num);
LCD_DisplayStringLine(Line6,text);
S_Num = A_Num - C_Num - V_Num;
sprintf((char *)text," I D L E:%d",S_Num);
LCD_DisplayStringLine(Line8,text);
}
if(view == 1) //界面二
{
sprintf((char *)text," P a r a");
LCD_DisplayStringLine(Line1,text);
sprintf((char *)text," C N B R:%.2f",mon_c);
LCD_DisplayStringLine(Line4,text);
sprintf((char *)text," V N B R:%.2f",mon_v);
LCD_DisplayStringLine(Line6,text);
}
}
工程文件可供参考:
链接:https://pan.baidu.com/s/1J3WGl59Q7vqRDJv5wrBKbw?pwd=7uw5
提取码:7uw5