1、第十二届第一场省赛真题
2、解题思路整理
- 本届赛题相较于往届赛题在串口部分有较为复杂的逻辑,想要解决还是需要下一番功夫的。首先除了串口模块,LED、LCD、按键、PA7输出频率固定、占空比固定的PWM这些模块都是基本的套路比较简单,先把这些逐个完成。
- 串口模块:串口接收车辆进入停车场的信息(车辆类型:车辆ID:进入时间年月日时分秒-
YYMMDDHHMMSS);车辆出停车场时的信息(车辆类型:车辆ID:出去时间年月日时分秒-YYMMDDHHMMSS)。
串口发送车辆出停车场时车辆信息、停车时间、停车费用(车辆类型:车辆ID:停车时间(小时-未满一小时按一小时计算):停车费用)。
- 初步判断串口接收在RX_BUF中的数据是否满足正确格式,例如:接收到的字符串长度为22、对应固定位置不改变的字符(CNBR、VNBR、:)正确、时间为0~9的数字。不满足格式则串口输出error。
- 如果初步判断字符符合正确格式,则开始对车辆信息进行处理。
- 当串口接收到一辆符合要求的车辆信息,通过车辆ID判断停车场中是否存在该车。
如果存在则该车为出停车场;串口输出车辆信息、停车时间、停车费用。(停车时间、停车费用应当大于0,否则串口输出error);清空对应车位的车辆信息、将车位非空标志置0表示该车位空闲。由于一年中有12个月,每个月的天数不同,故可将月份转化为天数计算用来处理不同月份天数跨度下对应的停车时间。
如果不存在则该车为入停车场,找空闲车位,将该车的车辆信息、进入时间存入对应车位的车辆信息、将车位非空标志置1表示该车位有车(当无空闲车位时,再有车辆进入则输出error)。
3、主函数部分代码
#include "main.h"
#include "rcc.h"
#include "led_key.h"
#include "lcd.h"
#include "tim.h"
#include "uart.h"
__IO uint32_t uwTick_LED_Speed_Ctrl;
__IO uint32_t uwTick_KEY_Speed_Ctrl;
__IO uint32_t uwTick_LCD_Speed_Ctrl;
__IO uint32_t uwTick_UART_Speed_Ctrl;
uint8_t ucLED;
uint8_t key_value,key_up,key_down;
static uint8_t key_old;
uint8_t LCD_String_Disp[21];
uint8_t RX_Buffer;
uint8_t RX_BUF[200];
uint8_t RX_Count;
_Bool Interface_Ctrl = 0;
uint8_t CNBR_cost = 35;
uint8_t VNBR_cost = 20;
_Bool B4_Ctrl = 0;
uint8_t CNBR_count = 0;
uint8_t VNBR_count = 0;
uint8_t IDLE_count = 8;
float stop_car_cost;
uint8_t year_365[12]={31,28,31,30,31,30,31,31,30,31,30,31};
uint8_t year_366[12]={31,29,31,30,31,30,31,31,30,31,30,31};
uint16_t month_trans_day_temp;
void SystemClock_Config(void);
void LED_Proc(void);
void KEY_Proc(void);
void LCD_Proc(void);
void UART_Proc(void);
_Bool CheckCmd(uint8_t *RX_str);
void sub_str(uint8_t *d_str,uint8_t *s_str,uint8_t locate,uint8_t length);
uint8_t find_locate(void);
uint8_t id_isExist(uint8_t *id_str);
uint16_t month_trans_day(uint8_t d_m,uint8_t s_m,uint8_t *month_a);
typedef struct car_information
{
uint8_t type_in[5];
uint8_t id_in[5];
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
_Bool notEmpty;
}car_information_storage;
car_information_storage car_num[9];
int main(void)
{
HAL_Init();
SystemClock_Config();
LED_KEY_Init();
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
USART1_UART_Init();
HAL_UART_Receive_IT(&huart1, (uint8_t *)(&RX_Buffer) ,1);
TIM17_Init();
while (1)
{
LED_Proc();
KEY_Proc();
LCD_Proc();
UART_Proc();
}
}
void LED_Proc(void)
{
if((uwTick - uwTick_LED_Speed_Ctrl)<200) return;
uwTick_LED_Speed_Ctrl = uwTick;
if(IDLE_count)
ucLED |= 0x01;
else
ucLED &= 0x02;
LED_Disp(ucLED);
}
void KEY_Proc(void)
{
if((uwTick - uwTick_KEY_Speed_Ctrl)<100) return;
uwTick_KEY_Speed_Ctrl = uwTick;
key_value = KEY_Scan();
key_down = key_value & (key_value ^ key_old);
key_up = ~key_value & (key_value ^ key_old);
key_old = key_value;
switch(key_down)
{
case 1:
Interface_Ctrl ^= 1;
LCD_Clear(Black);
break;
case 2:
if(Interface_Ctrl == 1)
{
CNBR_cost += 5;
VNBR_cost += 5;
}
break;
case 3:
if(Interface_Ctrl == 1)
{
if(VNBR_cost == 0)
{
CNBR_cost = 15;
VNBR_cost = 0;
}
else
{
CNBR_cost -= 5;
VNBR_cost -= 5;
}
}
break;
case 4:
B4_Ctrl ^= 1;
break;
}
}
void LCD_Proc(void)
{
if((uwTick - uwTick_LCD_Speed_Ctrl)<100) return;
uwTick_LCD_Speed_Ctrl = uwTick;
if(!B4_Ctrl)
{
HAL_TIM_PWM_Stop(&htim17 , TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1, 0);
HAL_TIM_PWM_Start(&htim17 , TIM_CHANNEL_1);
ucLED &= 0x01;
}
else
{
HAL_TIM_PWM_Stop(&htim17 , TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1, 100);
HAL_TIM_PWM_Start(&htim17 , TIM_CHANNEL_1);
ucLED |= 0x02;
}
if(!Interface_Ctrl)
{
memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
sprintf((char*)LCD_String_Disp , " Data");
LCD_DisplayStringLine(Line1 , LCD_String_Disp);
memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
sprintf((char*)LCD_String_Disp , " CNBR:%1d",CNBR_count);
LCD_DisplayStringLine(Line3 , LCD_String_Disp);
memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
sprintf((char*)LCD_String_Disp , " VNBR:%1d",VNBR_count);
LCD_DisplayStringLine(Line5 , LCD_String_Disp);
memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
sprintf((char*)LCD_String_Disp , " IDLE:%1d",IDLE_count);
LCD_DisplayStringLine(Line7 , LCD_String_Disp);
}
else
{
memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
sprintf((char*)LCD_String_Disp , " Para");
LCD_DisplayStringLine(Line1 , LCD_String_Disp);
memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
sprintf((char*)LCD_String_Disp , " CNBR:%4.2f" , (float)CNBR_cost/10);
LCD_DisplayStringLine(Line3 , LCD_String_Disp);
memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
sprintf((char*)LCD_String_Disp , " VNBR:%4.2f" , (float)VNBR_cost/10);
LCD_DisplayStringLine(Line5 , LCD_String_Disp);
}
}
void UART_Proc(void)
{
if((uwTick - uwTick_UART_Speed_Ctrl)<100) return;
uwTick_UART_Speed_Ctrl = uwTick;
if(CheckCmd(RX_BUF))
{
uint8_t car_type[5];
uint8_t car_id[5];
uint8_t stop_locate = 0xff;
uint8_t spare_locate;
uint8_t year_temp,month_temp,day_temp,hour_temp,min_temp,sec_temp;
float time_count;
year_temp = (RX_BUF[10]-0x30)*10+(RX_BUF[11]-0x30);
month_temp = (RX_BUF[12]-0x30)*10+(RX_BUF[13]-0x30);
day_temp = (RX_BUF[14]-0x30)*10+(RX_BUF[15]-0x30);
hour_temp = (RX_BUF[16]-0x30)*10+(RX_BUF[17]-0x30);
min_temp = (RX_BUF[18]-0x30)*10+(RX_BUF[19]-0x30);
sec_temp = (RX_BUF[20]-0x30)*10+(RX_BUF[21]-0x30);
if((month_temp>12)||(day_temp>30)||(hour_temp>23)||(min_temp>59)||(sec_temp>59))
{
printf("error\n");
}
else
{
sub_str(car_type , RX_BUF , 0 ,4);
sub_str(car_id , RX_BUF , 5 ,4);
stop_locate = id_isExist(car_id);
if(stop_locate!=0xff)
{
if(year_temp % 4 == 0)
{
month_trans_day_temp = month_trans_day(month_temp,car_num[stop_locate].month,year_366);
}
else
{
month_trans_day_temp = month_trans_day(month_temp,car_num[stop_locate].month,year_365);
}
time_count = (float)((year_temp-car_num[stop_locate].year)*365*24*3600)+(month_trans_day_temp*24*3600)+
((day_temp-car_num[stop_locate].day)*24*3600)+((hour_temp-car_num[stop_locate].hour)*3600+(min_temp-car_num[stop_locate].min)*60+
(sec_temp-car_num[stop_locate].sec));
time_count = (time_count + 3599)/3600;
if(time_count < 0)
{
printf("error\n");
}
else
{
if(car_type[0] == 'C')
{
CNBR_count--;
stop_car_cost = (uint16_t)time_count*((float)CNBR_cost/10);
}
else if(car_type[0] == 'V')
{
VNBR_count--;
stop_car_cost = (uint16_t)time_count*((float)VNBR_cost/10);
}
IDLE_count++;
printf("%s:%s:%d:%.2f\n",car_type,car_id,(uint16_t)time_count,stop_car_cost);
}
memset(&car_num[stop_locate] , 0 ,sizeof(car_num[stop_locate]));
}
else if(stop_locate == 0xff)
{
spare_locate = find_locate();
if(spare_locate!=0xff)
{
sub_str(car_num[spare_locate].type_in , car_type , 0 ,4);
sub_str(car_num[spare_locate].id_in , car_id , 0 ,4);
car_num[spare_locate].year = year_temp;
car_num[spare_locate].month = month_temp;
car_num[spare_locate].day = day_temp;
car_num[spare_locate].hour = hour_temp;
car_num[spare_locate].min = min_temp;
car_num[spare_locate].sec = sec_temp;
car_num[spare_locate].notEmpty = 1;
if(car_type[0] == 'C')
{
CNBR_count++;
}
else if(car_type[0] == 'V')
{
VNBR_count++;
}
IDLE_count--;
}
else
{
printf("error\n");
}
}
}
}
RX_Count = 0;
memset((char*)RX_BUF , 0 ,sizeof(RX_BUF));
}
_Bool CheckCmd(uint8_t *RX_str)
{
uint8_t i;
if(RX_Count != 22)
{
return 0;
}
if((RX_BUF[0]=='C'||RX_BUF[0]=='V')&&(RX_BUF[1]=='N')&&(RX_BUF[2]=='B')&&(RX_BUF[3]=='R')&&(RX_BUF[4]==':')&&(RX_BUF[9]==':'))
{
for(i=10;i<22;i++)
{
if((RX_BUF[i]>‘9’)
{
printf("error\n");
return 0;
}
}
}
else
{
printf("error\n");
return 0;
}
return 1;
}
void sub_str(uint8_t *d_str,uint8_t *s_str,uint8_t locate,uint8_t length)
{
uint8_t i;
for(i=0;i<length;i++)
{
d_str[i] = s_str[locate+i];
}
d_str[length] = '\0';
}
uint8_t id_isExist(uint8_t *id_str)
{
uint8_t i = 0;
for(i=0;i<8;i++)
{
if((strcmp((const char*)id_str,(const char*)car_num[i].id_in))== 0)
{
return i;
}
}
return 0xff;
}
uint8_t find_locate(void)
{
uint8_t i;
for(i=0;i<8;i++)
{
if(!car_num[i].notEmpty)
{
return i;
}
}
return 0xff;
}
uint16_t month_trans_day(uint8_t d_m,uint8_t s_m,uint8_t *month_a)
{
uint8_t i;
uint16_t day_sum = 0;
for(i=s_m-1;i<d_m-1;i++)
{
day_sum = day_sum + month_a[i];
}
return day_sum;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
RX_BUF[RX_Count] = RX_Buffer;
RX_Count++;
HAL_UART_Receive_IT(&huart1, (uint8_t *)(&RX_Buffer) ,1);
}
int fputc(int ch, FILE * f)
{
char c = ch;
HAL_UART_Transmit(&huart1 , (uint8_t *)&c , 1 ,50);
return ch;
}