感觉十二届的省赛还是比较难的,特别是对串口接收到的数据进行处理那块。
由于串口接收到的数据都是字符类型,所以需要一些对字符串进行处理的函数
//定义一个结构体数组将车辆的信息都存入其中
typedef struct car_park{
char type[5];
char id[5];
int year;
int month;
int day;
int hour;
int minute;
int second;
}car_park;
//定义一个结构体数组,就是其中八车库的数据
typedef struct Parking{
int can_park;
int size;
car_park car_infom;
}Parking[8];
car_park car_buff;
//该函数的功能就是将输入的字符串数组进行解析,将数据存入对应的结构体中,并且判断数据的合法性
int parseString(const char *inpit,car_park *car)
{
strncpy(car->type,input,4);//strncpy()该函数不会自动加'\0',故需要手动加上
car->type[4]='\0';
strncpy(car->id,input+5,4);
car->id[4]='\0';
sscanf(input+10,"%2u%2u%2u%2u%2u%2u",&car->year,&car->month,&car->day,
&car->hour,&car->minute,&car->second);
memset(input,0,sizeof(input));
if(strcmp(car->type,"VNBR")!=0 && strcmp(car->type,"CNBR")!=0)
{
sprintf((char*)Tx,"ERROR TYPE\n")
HAL_UART_Transmit(&huart1,Tx,strlen(Tx),50);
return 0;
}
if(car->month>12||car->day>31||
car->hour>24||car->minute>60||car->second>60)
{
sprintf((char*)Tx,"TIME ERROR\n")
HAL_UART_Transmit(&huart1,Tx,strlen(Tx),50);
return 0;
}
return 1;
}
以上我们实现了对串口数据的解析,例如输入CNBR:R258:201212100000
首先将该字符串存入串口接收数据数组中,然后将字符串解析存入结构体当中,包括车型,车牌,和进出时间。对时间进行解析的函数使用sscanf();如果对该函数不熟悉亦可对字符串减去'0',化为数字。如果数据不合法则返回0,如果数据合法则返回1,将其存入缓冲数组当中。
将数据解析后就进行入库出库判断,入库函数就是将缓冲数组接收到的数据与车库数组中的信息作比较,如果该车位数组中的can_park标志位为1则代表该车位闲置,然后将缓冲数组中的数据Parking_buff存入车位数组Parking[i]的信息当中
int Park(Parking *Parking,car_park *car_buff)
{
unsigned char type_flag;
unsigned char i;
if(Leisure<=0)
return 0;
if(strcmp(car_buff->type,"CNBR")==0)
type_flag=1;
if(strcmp(car_buff->type,"VNBR")==0)
type_flag=2;
for(i=0;i<8;i++)
{
if(Parking[i].can_park==1)
{
if(type_flag==1)
CNBR--;
if(type_flag==2)
VNBR--
Leisure--;
strcpr(Parking[i].car_inform.id,car_buff.id);
strcpr(Parking[i].car_inform.type,car_buff.type);
Parking[i].car_infom.year=car->year;
Parking[i].car_infom.month=car->month;
Parking[i].car_infom.day=car->day;
Parking[i].car_infom.hour=car->hour;
Parking[i].car_infom.minute=car->minute;
Parking[i].car_infom.second=car->second;
return 1;
}
}
return 0;
}
出库程序:
double Park_time;
double sum;
//在该示例中,对出库车辆的判断涉及对车费的计算
double goOut(Parking *Parking,car_part car_part,float CNBR_Price,float VNBR_Price)
{
int i;
float Price;
unsigned char type_flag;
car_part car_old;
if(strcmp(car_part.type,"CNBR")==0)
{
Price=CNBR_Price;
type_flag=1;
}
if(strcmp(car_part.type,"VNBR")==0)
{
Price=CNBR_Price;
type_flag=2;
}
//对Paeking数组进行遍历,如果发现相同车牌号,则计算时间价格后出库
for(i=0;i<8;i++)
{
car_old=Parking.car_infrom;
if(strcmp(car_part.id,car_old.id)==0)
{
if(type_flag==1)
{
Leisure++;
CNBR--;
}
if(type_flag==2)
{
Leisure++;
VNBR--;
}
Park_time=(car_part.year-car_old.year)*365*24+
(car_part.month-car_old.month)*30*24
+(car_part.day-car_old.day)*24;
if(Park_time<0)
return -2;//时间不合法
else if(Park_time==0)
{
if(((car_part.minute+car_part.hour*60)-
(car_old.minute+car_old.hour*60))<0)
return -2;//时间不合法
else
{
return Price;
Init_park(Parking,i);
}
}
else
{
Init_park(Parking,i);
sum=Price*Park_time;
return sum;
}
}
}
return -1;
}
unsigned char isRxCaplt(void)
{
if(Rx_point!=22)
return 0;
if(((Rx[0]=='C')||(Rx[0]=='V'))&&(Rx[1]=='N')&&
(Rx[2]=='B')&&(Rx[3]=='R')&&(Rx[4]==':')&&(Rx[9]==':'))
{
unsigned char i;
for(i=0;i<22;i++)
{
if((Rx[i]>'9')&&(Rx[i]<'0'))
return 0;
}
return 1;
}
}
void UART_Proc(void)
{
if(uwTick-UART_tick<100) return;
UART_tick=uwTick;
if(isRxCaplt())
{
parseString(Rx,&car_buff);
sum=goout(park_inf,car_buff,C_price,V_price);
if(sum==-1.0)
{
if(park(park_inf,&car_buff)==1)
{
sprintf((char*)Rx,"Success Park\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
else if(park(park_inf,&car_buff)==0)
{
sprintf((char*)Rx,"Error Park\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
// sprintf((char*)Rx,"Success Park\n");
// HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
}
if(sum==-2)
{
sprintf((char*)Rx,"Error Parktime\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
if(sum>=0)
{
sprintf((char*)Rx,"%s:%s:%dhour:%.0f$\n",car_buff.id,car_buff.type,park_time,sum);
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
Rx_point=0;
}
}
所有代码汇总
__IO uint32_t Key_tick,Lcd_tick,Led_tick,UART_tick;
//key
unsigned char Key_value,Key_old,Key_down,Key_up;
//lcd
unsigned char Page=1;
unsigned char String_[20];
unsigned char CNBR=0,VNBR=0;
unsigned char Leisure=8;//¿ÕÏÐÊýÄ¿
float C_price=3.5,V_price=2.0;
//pwm
unsigned char Pwm_mode;
//uart
int park_time;
double sum;
unsigned char Rxdata;
unsigned char Rx_point;
unsigned char Rx[30];
unsigned char Tx[30];
typedef struct {
char type[5];
char id[5];
int year;
int month;
int day;
int hour;
int minute;
int second;
}car_part;
typedef struct {
car_part car_inf;
int size;
int can_park;
}Parking;
car_part car_buff;
Parking parking;
Parking park_inf[8];
void Lcd_proc(void);
void Key_proc(void);
void Led_proc(void);
void UART_Proc(void);
void Initpart(Parking* parking,int location);
unsigned char isRxCaplt(void);
double goout(Parking* parking,car_part car,float cnbr_price,float vnbr_price);
int park(Parking* parking,car_part* car);
void Init_park(void);
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
Initpart(park_inf,8);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,0);
HAL_UART_Receive_IT(&huart1,&Rxdata,1);
Init_park();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
Lcd_proc();
Key_proc();
Led_proc();
UART_Proc();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
Rx[Rx_point++]=Rxdata;
HAL_UART_Receive_IT(&huart1,&Rxdata,1);
}
unsigned char isRxCaplt(void)
{
if(Rx_point!=22)
return 0;
if(((Rx[0]=='C')||(Rx[0]=='V'))&&(Rx[1]=='N')&&
(Rx[2]=='B')&&(Rx[3]=='R')&&(Rx[4]==':')&&(Rx[9]==':'))
{
unsigned char i;
for(i=0;i<22;i++)
{
if((Rx[i]>'9')&&(Rx[i]<'0'))
return 0;
}
return 1;
}
}
void UART_Proc(void)
{
if(uwTick-UART_tick<100) return;
UART_tick=uwTick;
if(isRxCaplt())
{
parseString(Rx,&car_buff);
sum=goout(park_inf,car_buff,C_price,V_price);
if(sum==-1.0)
{
if(park(park_inf,&car_buff)==1)
{
sprintf((char*)Rx,"Success Park\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
else if(park(park_inf,&car_buff)==0)
{
sprintf((char*)Rx,"Error Park\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
// sprintf((char*)Rx,"Success Park\n");
// HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
}
if(sum==-2)
{
sprintf((char*)Rx,"Error Parktime\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
if(sum>=0)
{
sprintf((char*)Rx,"%s:%s:%dhour:%.0f$\n",car_buff.id,car_buff.type,park_time,sum);
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
}
Rx_point=0;
}
}
int parseString(const char *input,car_part *car)
{
strncpy(car->type,input,4);//strncpy²»»á×Ô¶¯¼ÓÉÏÖÕÖ¹·û£¬¹ÊÐèÒªÊÖ¶¯¼ÓÉÏ
car->type[4]='\0';
strncpy(car->id,input+5,4);
car->id[4]='\0';
sscanf(input+10,"%2u%2u%2u%2u%2u%2u",&car->year, &car->month, &car->day,
&car->hour, &car->minute, &car->second);
memset(Rx,0,sizeof(Rx));
if(strcmp(car->type,"VNBR")!=0&&strcmp(car->type,"CNBR")!=0)
{
sprintf((char*)Rx,"Error Type Format\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
return 0;
}
else if(car->month>12||car->day>31||car->hour>24||car->minute>60||car->second>60)
{
sprintf((char*)Rx,"Time Format\n");
HAL_UART_Transmit(&huart1,Rx,strlen(Rx),50);
return 0;
}
else
return 1;
}
int park(Parking* parking,car_part* car)//1 Í£³µÍê³É 0 ûÓпÕλ
{
unsigned char i=0;
unsigned char type_flag;
if(Leisure<=0)
{
return 0;
}
if(strcmp(car->type,"CNBR")==0)
type_flag=1;
if(strcmp(car->type,"VNBR")==0)
type_flag=2;
for(i=0;i<8;i++)
{
if(parking[i].can_park==1)
{
if(type_flag==1)
{
CNBR++;
Leisure--;
}
if(type_flag==2)
{
VNBR++;
Leisure--;
}
strcpy(parking[i].car_inf.id,car->id);
strcpy(parking[i].car_inf.type,car->type);
parking[i].car_inf.year=car->year;
parking[i].car_inf.month=car->month;
parking[i].car_inf.day=car->day;
parking[i].car_inf.hour=car->hour;
parking[i].car_inf.minute=car->minute;
parking[i].car_inf.second=car->second;
parking[i].can_park=0;
return 1;
}
}
return 0;
}
double goout(Parking* parking,car_part car,float cnbr_price,float vnbr_price)
{
int i=0;
float price;
unsigned char type_flag;
car_part oldcar;
if(strcmp(car.type,"CNBR")==0)
{
price=cnbr_price;
type_flag=1;
}
if(strcmp(car.type,"VNBR")==0)
{
price=vnbr_price;
type_flag=2;
}
for(i=0;i<8;i++)
{
oldcar=parking[i].car_inf;
if(parking[i].can_park==1)
{
continue;
}
if(strcmp(oldcar.id,car.id)==0)
{
if(type_flag==1)
{
CNBR--;
Leisure++;
}
if(type_flag==2)
{
VNBR--;
Leisure++;
}
park_time=(car.year-oldcar.year)*365*24+
(car.month-oldcar.month)*30*24+
(car.hour-oldcar.hour);
if(park_time<0)
{
park_time=0;
return -2;
}
else if(park_time==0)
{
if(((car.minute*60+car.second)-(oldcar.minute*60+oldcar.second))<0)
{
return -2;
}
else
{
Initpart(parking,i);
return price;
}
}
else
{
strcpy(parking[i].car_inf.id," ");
strcpy(parking[i].car_inf.id," ");
parking[i].car_inf.year=0;
parking[i].car_inf.month=0;
parking[i].car_inf.day=0;
parking[i].car_inf.hour=0;
parking[i].car_inf.minute=0;
parking[i].car_inf.second=0;
parking[i].can_park=1;
sum=price*(float)park_time;
}
return sum;
}
}
return -1;
}
void Initpart(Parking* parking,int location)
{
for(location=0;location<8;location++)
{
strcpy(parking[location].car_inf.id," ");
strcpy(parking[location].car_inf.id," ");
parking[location].car_inf.year=0;
parking[location].car_inf.month=0;
parking[location].car_inf.day=0;
parking[location].car_inf.hour=0;
parking[location].car_inf.minute=0;
parking[location].car_inf.second=0;
parking[location].can_park=1;
}
return;
}
void Init_park(void)
{
park_inf[0].can_park=1;
park_inf[1].can_park=1;
park_inf[2].can_park=1;
park_inf[3].can_park=1;
park_inf[4].can_park=1;
park_inf[5].can_park=1;
park_inf[6].can_park=1;
park_inf[7].can_park=1;
}
void Lcd_proc(void)
{
if(uwTick-Lcd_tick<50) return;
Lcd_tick=uwTick;
if(Page==1)
{
sprintf((char*)String_," Data");
LCD_DisplayStringLine(Line1,String_);
sprintf((char*)String_," CNBR:%d",CNBR);
LCD_DisplayStringLine(Line3,String_);
sprintf((char*)String_," VNBR:%d",VNBR);
LCD_DisplayStringLine(Line5,String_);
sprintf((char*)String_," IDLE:%d",Leisure);
LCD_DisplayStringLine(Line7,String_);
}
else if(Page==2)
{
sprintf((char*)String_," Para");
LCD_DisplayStringLine(Line1,String_);
sprintf((char*)String_," CNBR:%3.2f",C_price);
LCD_DisplayStringLine(Line3,String_);
sprintf((char*)String_," VNBR:%3.2f",V_price);
LCD_DisplayStringLine(Line5,String_);
}
sprintf((char*)String_," pwm_mode:%d",Pwm_mode);
LCD_DisplayStringLine(Line2,String_);
}
void Key_proc(void)
{
if(uwTick-Key_tick<50) return;
Key_tick=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;
if(Key_down==1)
{
LCD_Clear(Black);
if(Page==1)
Page=2;
else if(Page==2)
Page=1;
}
else if(Key_down==2)
{
if(Page==2)
{
C_price+=0.5;
V_price+=0.5;
}
}
else if(Key_down==3)
{
if(Page==2)
{
C_price-=0.5;
V_price-=0.5;
if(C_price<=0)
C_price=0;
if(V_price<=0)
V_price=0;
}
}
else if(Key_down==4)
{
if(Pwm_mode)
{
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,0);
Pwm_mode=0;
}
else
{
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,299);
Pwm_mode=1;
}
}
}
unsigned char lednum;
void Led_proc(void)
{
if(uwTick-Led_tick<100) return;
Led_tick=uwTick;
if(Leisure)
lednum|=0x01;
else
lednum&=0xfe;
if(Pwm_mode)
lednum|=0x02;
else
lednum&=0xfd;
Led_disp(lednum);
}