主要逻辑代码按照执行顺序进行展示(全部代码直接翻到最下边)
1.串口接收回调函数,接收任意长度的字符串,详细见博客:(1条消息) 手把手STM32串口不定长字符接收教程——基于HAL_usart_isr_idle和usart_sr_idle_hackercircle的博客-CSDN博客
void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart)
{
// Print received Bytes
// printf("\n\r[IDLE]Received %d Bytes:",__Rev_Size);
// for(uint16_t i = 0; i < __Rev_Size; i++)
// {
// printf((char *)__UART_RX_Buf[i]);
// }
// HAL_UART_Transmit(&huart1, __UART_RX_Buf, __Rev_Size, 100);
HAL_UART_Receive_DMA(&huart1, __UART_RX_Buf, __BUFFER_SIZE);
/* Enable the UART IDLE Interrupt*/
SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
Rx_Count++; //Rx计数++
Data_Judge(__UART_RX_Buf); //判断所接收数据为何种情况
}
判断接收到的字符串的合法性。
_Bool Rx_Check(uint8_t * str)
{
if(__Rev_Size!=22)
return 0;
if((str[0]=='C'||str[0]=='V')&&(str[1]=='N')&&(str[2]=='B')&&(str[3]=='R')&&(str[4]==':')&&((str[5]=='A')||(str[5]=='D')))
{
for(uint8_t i=6;i<=8;i++)
{
if(str[i]>'9'||str[i]<'0')
return 0;
}
return 1;
}
}
通过接收到的字符串信息判断所对应车辆的类型以及出库入库情况。
void Data_Judge(uint8_t * str)
{
//车辆为出库的情况
if((str[0]=='C')&&((Rx_Check(str))==1)&&(Did_Exist(str)!=0)) //类型为CNBR且是正确的数据并且为出库
{
CNBR_Num=CNBR_Num-1;
IDLE_Num=IDLE_Num+1;
//判断车位数据是否异常
if((CNBR_Num>8)||(IDLE_Num>8))
{
CNBR_Num=CNBR_Num-1;
IDLE_Num=IDLE_Num+1;
}
RxR_Count++; //正确收到的次数++
Dif_Count=Dif_Count-1; //可用车位-1
Spend_Cal(str);
memset(&Type_Storage[Did_Exist(str)-1],0,sizeof(Type_Storage[Did_Exist(str)-1]));
Judge_Temp=1;
}
else if((str[0]=='V')&&(Rx_Check(str))==1&&(Did_Exist(str)!=0)) //类型为VNBR且为正确的数据并且为出库
{
VNBR_Num=VNBR_Num-1;
IDLE_Num=IDLE_Num+1;
//判断车位数据是否异常
if((VNBR_Num>8)||(IDLE_Num>8))
{
VNBR_Num=VNBR_Num-1;
IDLE_Num=IDLE_Num+1;
}
RxR_Count++; //正确收到的次数++
Dif_Count=Dif_Count-1; //可用车位-1
Spend_Cal(str);
memset(&Type_Storage[Did_Exist(str)-1],0,sizeof(Type_Storage[Did_Exist(str)-1]));
Judge_Temp=1;
}
//车辆为进入的情况
if((str[0]=='C')&&((Rx_Check(str))==1)&&(Did_Exist(str)==0)&&Judge_Temp!=1) //类型为CNBR且是正确的数据并且为进入
{
CNBR_Num++;
IDLE_Num=IDLE_Num-1;
//判断车位数据是否异常
if((CNBR_Num>8)||(IDLE_Num>8))
{
CNBR_Num=CNBR_Num-1;
IDLE_Num=IDLE_Num+1;
}
Rx_Storage(str); //存储信息
RxR_Count++; //正确收到的次数++
Dif_Count++; //可用车位+1
}
else if((str[0]=='V')&&(Rx_Check(str))==1&&(Did_Exist(str)==0)&&Judge_Temp!=1) //类型为VNBR且为正确的数据并且为进入
{
VNBR_Num++;
IDLE_Num=IDLE_Num-1;
//判断车位数据是否异常
if((VNBR_Num>8)||(IDLE_Num>8))
{
VNBR_Num=VNBR_Num-1;
IDLE_Num=IDLE_Num+1;
}
Rx_Storage(str); //存储信息
RxR_Count++; //正确收到的次数++
Dif_Count++; //可用车位+1
}
Judge_Temp=0;
}
判断汽车ID是否已经存在(是否为出库车辆)
//判断汽车ID是否已经存在
uint8_t Did_Exist(uint8_t* str)
{
uint8_t i=0;
Sub_Str(Car_Id_Temp,str,5,4); //提取车辆ID
Sub_Str(Car_Type_Temp,str,0,4); //提取车辆类型
for(i=0;i<8;i++)
{
if(Car_Id_Temp[0]==Type_Storage[i].Id[0] && Car_Id_Temp[1]==Type_Storage[i].Id[1] && Car_Id_Temp[2]==Type_Storage[i].Id[2] && Car_Id_Temp[3]==Type_Storage[i].Id[3]&&Car_Type_Temp[0]==Type_Storage[i].Type[0]) //字符串匹配,确认字符串存在
{
memset(Car_Id_Temp,0,sizeof(Car_Id_Temp));
return (i+1); //有的情况下返回位置
}
}
memset(Car_Id_Temp,0,sizeof(Car_Id_Temp));
return 0; //没有的情况下返回0
}
存储车辆数据函数
//存储函数
void Rx_Storage(uint8_t * str)
{
uint8_t i;
//日期中间变量赋值
Year_temp=((str[10]-'0')*10)+((str[11]-'0'));
Month_Temp=((str[12]-'0')*10)+((str[13]-'0'));
Day_Temp=((str[14]-'0')*10)+((str[15]-'0'));
Hour_Temp=((str[16]-'0')*10)+((str[17]-'0'));
Min_Temp=((str[18]-'0')*10)+((str[19]-'0'));
Sec_Temp=((str[20]-'0')*10)+((str[21]-'0'));
//传递字符串
Sub_Str(Car_Id_Buff,str,5,4); //提取车辆ID
Sub_Str(Car_Type_Buff,str,0,4); //提取车辆类型
//查找空位存储
for(i=0;i<=7;i++)
{
if(Type_Storage[i].Not_Empty==0)
{
Empty_Station=i;
break;
}
}
//存储数据到数据库
//存储ID
Type_Storage[Empty_Station].Id[0]=Car_Id_Buff[0];
Type_Storage[Empty_Station].Id[1]=Car_Id_Buff[1];
Type_Storage[Empty_Station].Id[2]=Car_Id_Buff[2];
Type_Storage[Empty_Station].Id[3]=Car_Id_Buff[3];
//存储类型
Type_Storage[Empty_Station].Type[0]=Car_Type_Buff[0];
Type_Storage[Empty_Station].Type[1]=Car_Type_Buff[1];
Type_Storage[Empty_Station].Type[2]=Car_Type_Buff[2];
Type_Storage[Empty_Station].Type[3]=Car_Type_Buff[3];
//存储时间
Type_Storage[Empty_Station].Year_In=Year_temp;
Type_Storage[Empty_Station].Mon_In=Month_Temp;
Type_Storage[Empty_Station].Day_In=Day_Temp;
Type_Storage[Empty_Station].Hour_In=Hour_Temp;
Type_Storage[Empty_Station].Min_In=Min_Temp;
Type_Storage[Empty_Station].Sec_In=Sec_Temp;
Type_Storage[Empty_Station].Not_Empty=1;
}
用于存储车辆数据的数据库结构体
#ifndef __UART_Deal_H__
#define __UART_Deal_H__
#include "main.h"
_Bool Rx_Check(uint8_t * str);
void Data_Judge(uint8_t * str);
//车辆信息
typedef struct
{
uint8_t Type[5];
uint8_t Id[5];
uint8_t Year_In;
uint8_t Mon_In;
uint8_t Day_In;
uint8_t Hour_In;
uint8_t Min_In;
uint8_t Sec_In;
_Bool Not_Empty;
}Type_Storage_Type;
extern Type_Storage_Type Type_Storage[8]; //用于存储进来的8个车的信息
#endif
完整代码(hal库):
链接:https://pan.baidu.com/s/1qbGHw4NlANJ-eWBuihWEvw?pwd=1234
提取码:1234