蓝桥杯备赛——第十二届省赛第一场(模拟停车场)

本届赛题难度偏大,主要难在关于串口的逻辑部分。仅使用串口中断也能较好地完成本题目。
预备函数:

_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);
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值