题目
变量
采用结构数组来构建8个停车位的数据
__IO uint32_t uwTick_usart1;
__IO uint32_t uwTick_Lcd_Set_Point;
__IO uint32_t uwTick_Key_Set_Point;
void SystemClock_Config(void);
void lcd_display(void);
_Bool CheckCmd(uint8_t* str);
void substr(uint8_t* d_str,uint8_t* s_str,uint8_t locate,uint8_t lenght);
uint8_t exist(uint8_t* str);
uint8_t findLocate(void);
void usart_proc(void);
void key_proc(void);
uint8_t Key_Scan(void);
void led_proc(void);
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;
//8个车位--结构数组
typedef struct{
uint8_t type[5];
uint8_t id[5];
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
uint8_t notempty; //是否空车位
}car_data_storage_type;
car_data_storage_type car_data_storage[8];
float para_cnbr=3.50; //初始cnbr价格
float para_vnbr=2.00; //初始vnbr价格
uint8_t cnbr_use_num; //cnbr停车数量
uint8_t vnbr_use_num; //vnbr停车数量
uint8_t no_use_num=8; //空车位
uint8_t tx_data[40];
uint8_t rx_data[200]; //接收缓存
uint8_t rx_counter; //接收数据量,应用于接收缓存数组下标
uint8_t rx_buffer;
uint8_t lcd_data[21];
uint8_t interface=0; //界面
uint8_t led_data;
uint8_t pwm_cut; //pwm切换
按键
之前按键一直用的定时器更新中断来检测,提交到4t测试发现不行,而后参考
第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)_蓝桥杯嵌入式第六届客观题-优快云博客
按键扫描
uint8_t Key_Scan(void)
{
uint8_t unKey_Val = 0;
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)
unKey_Val = 1;
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)
unKey_Val = 2;
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)
unKey_Val = 3;
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
unKey_Val = 4;
return unKey_Val;
}
按键按下操作
void key_proc(void)
{
if((uwTick - uwTick_Key_Set_Point)<50) return;//减速函数
uwTick_Key_Set_Point = uwTick;
ucKey_Val = Key_Scan();
unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val);
ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val);
ucKey_Old = ucKey_Val;
switch(unKey_Down)
{
case 1://B1
interface ^= 0x1; //切换界面
LCD_Clear(Black);
break;
case 2://B2
if(interface == 1)
{
para_cnbr += 0.5;
para_vnbr += 0.5;
}
break;
case 3://B3
if(interface == 1)
{
if((para_vnbr - 0.5)> 0)
{
para_cnbr -= 0.5;
para_vnbr -= 0.5;
}
}
break;
case 4://B4
pwm_cut ^= 0x1;
if(pwm_cut == 0)//低电平
{
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1, 0);//强制配置成低电平
}
else//高电平
{
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1, 100);//强制配置成PWM电平
}
break;
}
}
lcd显示
void lcd_display(void)
{
if((uwTick - uwTick_Lcd_Set_Point)<100) return;//减速函数
uwTick_Lcd_Set_Point = uwTick;
//车位显示界面
if(interface==0)
{
sprintf((char*)lcd_data," Data");
LCD_DisplayStringLine(Line1,lcd_data);
sprintf((char*)lcd_data," CNBR:%1d",cnbr_use_num);
LCD_DisplayStringLine(Line3,lcd_data);
sprintf((char*)lcd_data," VNBR:%1d",vnbr_use_num);
LCD_DisplayStringLine(Line5,lcd_data);
sprintf((char*)lcd_data," IDLE:%1d",no_use_num);
LCD_DisplayStringLine(Line7,lcd_data);
}
//费率设置界面
else if(interface==1)
{
sprintf((char*)lcd_data," Para");
LCD_DisplayStringLine(Line1,lcd_data);
sprintf((char*)lcd_data," CNBR:%4.2f",para_cnbr);
LCD_DisplayStringLine(Line3,lcd_data);
sprintf((char*)lcd_data," VNBR:%4.2f",para_vnbr);
LCD_DisplayStringLine(Line5,lcd_data);
}
}
led
void led_proc(void)
{
if(no_use_num>0) //空车位亮灯
{
led_data|=0x01;
}else if(no_use_num<=0)
{
led_data&=~(0x01);
}
if(pwm_cut==1)
{
led_data|=0x02;
}
else
{
led_data&=~(0x2);
}
led_display(led_data);
}
串口
最后是串口的编写,也是最难的部分,这套题学会了goto的用法,strcmp函数,巩固了memset函数。
需要先编写四个函数,个人觉得这俩函数很有移植的价值,写法可以学习一下
判断接收信息是否合法
_Bool CheckCmd(uint8_t* str)
{
if(rx_counter!=22)return 0;
if(((str[0]=='C')&&(str[0]=='V'))&&(str[1]=='N')&&(str[2]=='B')&&(str[3]=='R')&&(str[4]==':')&&(str[9]==':'))
{
uint8_t i;
for(i=10;i<22;i++) //数字区判断
{
if(str[i]>'9'||str[i]<'0')
{
return 0;
}
}
return 1;
}
}
长字符串提取短字符函数
//长字符串提取短字符函数
//参数1:存储字符串
//参数2:待提取字符串
//参数3:要开始提取位置
//参数4:长度
void substr(uint8_t* d_str,uint8_t* s_str,uint8_t locate,uint8_t lenght)
{
uint8_t i=0;
for(i=0;i<lenght;i++)
{
d_str[i]=s_str[locate+i];
}
d_str[lenght]='\0';
}
判断id是否相同
//判断id是否相同
uint8_t exist(uint8_t* str)
{
uint8_t i=0;
for(i=0;i<8;i++)
{
if((strcmp((const char*)str,(const char*)car_data_storage[i].id))==0)//符合
{
return i;
}
}
return 0XFF;
}
查询空位
//查询空位
uint8_t findLocate(void)
{
uint8_t i=0;
for(i=0;i<=7;i++)
{
if(car_data_storage[i].notempty==0)return i;
}
return 0xFF;
}
回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
rx_data[rx_counter]=rx_buffer;
rx_counter++;
HAL_UART_Receive_IT(&huart1,(uint8_t *)&rx_buffer,1);
}
}
主程序
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
Key_GPIO_Init();
led_GPIO_Init();
LCD_Init();
LCD_Clear(Black);
LCD_SetTextColor(White);
LCD_SetBackColor(Black);
USART1_UART_Init();
TIM17_Init();
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,0);
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
HAL_UART_Receive_IT(&huart1,(uint8_t*)&rx_buffer,1);
while (1)
{
led_proc();
usart_proc();
key_proc();
lcd_display();
}
}
C语言笔记:
代码参考: