本届赛题难度偏大,主要难在关于串口的逻辑部分。仅使用串口中断也能较好地完成本题目。
预备函数:
_Bool CheckCmd(uint8_t* str);
void substr(uint8_t* d_str, uint8_t* s_str, uint8_t locate, uint8_t length);
uint8_t isExist(uint8_t* str);
uint8_t findLocate(void);
函数功能:判断串口接收到的数据流是否规范
_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;
}
函数功能:从字符串中提取出一段字符串(进入车辆的信息的储存)
void substr(uint8_t* d_str, uint8_t* s_str, uint8_t locate, uint8_t length)
{
uint8_t i = 0;
for(i=0; i<length; i++)
{
d_str[i] = s_str[locate + i];
}
d_str[length] = '\0';
}
函数功能:判断车的ID是否在车库里面
uint8_t isExist(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;
}
串口接受函数的构建:
1.判断数据个数及数据格式是否合法;
2.验证日期和时间是否合法;
3.车辆进入的程序;
4.车辆出去的程序;
void Usart_Proc(void)
{
if(uwTick - uwTick_Usart_Set_Point <= 100)
return;
uwTick_Usart_Set_Point = uwTick;
if(CheckCmd(RX_BUF))//判断数据个数及数据格式是否合法;
{
year_temp = (RX_BUF[10] - '0') * 10 + (RX_BUF[11] - '0');
month_temp = (RX_BUF[12] - '0') * 10 + (RX_BUF[13] - '0');
day_temp = (RX_BUF[14] - '0') * 10 + (RX_BUF[15] - '0');
hour_temp = (RX_BUF[16] - '0') * 10 + (RX_BUF[17] - '0');
min_temp = (RX_BUF[18] - '0') * 10 + (RX_BUF[19] - '0');
sec_temp = (RX_BUF[20] - '0') * 10 + (RX_BUF[21] - '0');
//验证日期和时间是否合法
if((month_temp > 12) || (day_temp> 31) || (hour_temp > 23) || (min_temp > 59) || (sec_temp > 59))
{
goto SEND_ERROR;
}
substr(car_id, RX_BUF, 5, 4);//提取车的ID
substr(car_type, RX_BUF, 0, 4);//提取车的类型
/*************************车辆还没有进入*************************/
if(isExist(car_id) == 0xFF)
{
uint8_t locate = FindLocate();
if(locate == 0xFF)
{
goto SEND_ERROR;
}
//准备存储
substr(Car_Data_Storage[locate].type, car_type, 0, 4);//把当前车的类型存入
substr(Car_Data_Storage[locate].id, car_id, 0, 4);//把当前车的ID存入
Car_Data_Storage[locate].year_in = year_temp;
Car_Data_Storage[locate].month_in = month_temp;
Car_Data_Storage[locate].day_in = day_temp;
Car_Data_Storage[locate].hour_in = hour_temp;
Car_Data_Storage[locate].min_in = min_temp;
Car_Data_Storage[locate].sec_in = sec_temp;
Car_Data_Storage[locate].notEmpty = 1;
if(Car_Data_Storage[locate].type[0] == 'C')
ucNum_CNBR++;
else if(Car_Data_Storage[locate].type[0] == 'V')
ucNum_VNBR++;
ucNum_IDLE--;
}
/*************************车辆已经进入,准备出去*************************/
else
{
int64_t Second_derta;//用于核算小时的差值
uint8_t in_locate = isExist(car_id);//记录在停车库中的位置
if(strcmp((const char*)car_type, (const char*)Car_Data_Storage[in_locate].type) != 0)//说明不匹配(不同型号的车,同样的车牌号是存在问题的)
{
goto SEND_ERROR;
}
Second_derta = (year_temp - Car_Data_Storage[in_locate].year_in) * 365 * 24 * 60 * 60 +\
(month_temp - Car_Data_Storage[in_locate].month_in) * 30 * 24 * 60 * 60 +\
(day_temp - Car_Data_Storage[in_locate].day_in) * 24 * 60 * 60 +\
(hour_temp - Car_Data_Storage[in_locate].hour_in) * 60 * 60 +\
(min_temp - Car_Data_Storage[in_locate].min_in) * 60 +\
(sec_temp - Car_Data_Storage[in_locate].sec_in);
if(Second_derta < 0)//超前出去判断
{
goto SEND_ERROR;
}
Second_derta = (Second_derta + 3599) / 3600;
sprintf((char*)str_str, "%s:%s:%d:%.2lf\r\n", Car_Data_Storage[in_locate].type, Car_Data_Storage[in_locate].id, (unsigned int)Second_derta, ((double)Second_derta * (Car_Data_Storage[in_locate].type[0] == 'C' ? Ratio_CNBR : Ratio_VNBR)));
HAL_UART_Transmit(&huart1,(unsigned char *)str_str, strlen((char*)str_str), 50);
if(Car_Data_Storage[in_locate].type[0] == 'C')
ucNum_CNBR--;
else if(Car_Data_Storage[in_locate].type[0] == 'V')
ucNum_VNBR--;
ucNum_IDLE++;
memset(&Car_Data_Storage[in_locate],0,sizeof(Car_Data_Storage[in_locate]));//清空该位置的所有内容
}
goto CMD_YES;
SEND_ERROR:
sprintf(str_str, "Error:%1u\r\n", i_1);
HAL_UART_Transmit(&huart1,(unsigned char *)str_str, strlen(str_str), 50);
CMD_YES:
memset(&RX_BUF[0], 0, sizeof(RX_BUF));
Rx_Counter = 0;
}
}
串口接收中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
RX_BUF[Rx_Counter] = rx_buffer;
Rx_Counter++;
HAL_UART_Receive_IT(&huart1, (uint8_t *)(&rx_buffer), 1);
}