十二届蓝桥杯嵌入式省赛

停车计费系统

文章目录

  • 停车计费系统
    • 前言
    • 关于题目
    • 主要功能展示
    • 总体思路
    • 关键代码
      • 设计出入库的算法
      • 串口中断
      • 拆分串口接受数组
    • 归纳总结

前言

最近开始了22十二届蓝桥杯的培训,星期三的时候学弟陈给我说一起去试试一下去年的省题,但是我当时还是比较急的,前段时间的电赛,然后被隔离,回到正常的课程里面后,因为大三的课程还是比较多的,然后补了很多多作业,一直没有开始做,最后在星期五的下午,我看见学弟在做了,也就按耐不住做了起来哈哈,然后我就从星期五下午6点到晚上2点实现了全部功能,抛去做其他事情的时间,一共花了我接近6个小时,正式比赛的时候应该是5个小时,虽然到时候是沉寂式5个小时,但因为比赛时封闭的,可能倒是,因为后面还有其他项目做,所以比较急的。平时其实不会这么肝哈就。

关于题目

这个题目是对我来说,难度是那种能做出来,但是还是有点费力的,主要的难点在于如何将将接收到的串口返回数组拆分成几个参量,去进行做分析处理。

主要功能展示

十二届蓝桥杯嵌入式省赛_第1张图片 十二届蓝桥杯嵌入式省赛_第2张图片
十二届蓝桥杯嵌入式省赛_第3张图片 十二届蓝桥杯嵌入式省赛_第4张图片
十二届蓝桥杯嵌入式省赛_第5张图片 十二届蓝桥杯嵌入式省赛_第6张图片
十二届蓝桥杯嵌入式省赛_第7张图片 十二届蓝桥杯嵌入式省赛_第8张图片
改价格界面 十二届蓝桥杯嵌入式省赛_第9张图片
加钱 十二届蓝桥杯嵌入式省赛_第10张图片
减钱 十二届蓝桥杯嵌入式省赛_第11张图片

总体思路

这道题是实际生活中,我们经常遇到的,假设一个停车场有10个车位,我是先给定义了一个结构体数组,每个数组即代表一个车位,车位的信息就包括,对应车位上车子的信息,有车牌号、车型,入库时间三个成员。同时设置了相同结构体“虚拟车”,也是具有这三个成员的。

一旦串口发送信息过来,设置程序将串口接受数值,拆分为几个小数组,便于后边的计算,然后将这几个数组赋值给“虚拟车”的各个结构体变量。这样操作后,我们的当串口发送信息时,我们的“虚拟车”就会实时刷新得到便于处理的信息。然后时处理信息的部分,我们每次处理信息必须在接受串口数组完成后执行,而且只能进行一次。所以我们应该处理函数写道,串口接受完成后,触发的函数中。处理函数的话,主要的思想就是,先遍历着比较这10个车位中是否有何虚拟车一样的信息,(1)如果有那么就执行出库操作,计算时间价格,同时清空这个车位信息。(2)如果没有相同的车位信息,那么就执行入库操作,遍历这10个车位,如果遍历到这个车位时空的话,跳出遍历,同时将虚拟车的信息全部赋值给这个车位,完成入库操作。

关键代码

设计出入库的算法

void panduanjinchu(){
    if(RXOVER){ //这里做了一下限制,实现一点的报错功能
	if((USART_RXBUF[1]=='N')&&(USART_RXBUF[2]=='B')&&(USART_RXBUF[3]=='R')&&(USART_RXBUF[4]==':')&&(USART_RXBUF[9]==':')){
		USART_SendString("\n");
		USART_SendString(USART_RXBUF);
		USART_SendString("\n");
		RXOVER = 0;
		iii++;//接受串口的次数,这里的1s是防抖,完成一次后执行的程序,不过后面好像没用了。。
		//判断出库,顺便计算价钱
        //注意这里的panduan()函数就可以用来判断对应车位信息是否和虚拟车位相等。
		if((panduan(1)==1)||(panduan(2)==1)||(panduan(3)==1)||(panduan(4)==1)||(panduan(5)==1)||(panduan(6)==1)||(panduan(7)==1)||(panduan(8)==1)){	for(i=1;i<9;i++){
            	if((panduan(i)==1)){//具体哪一位车出去
				cccc[i]=0;		  //这个数组代表8个车位,对应车位空
				for(j=0;j<2;j++){
				tim_s1[j]=CHAR.cartime[j+8];	
				tim_s2[j]=char1[i].cartime[j+8];//分别得到秒钟部分
				}							
				time1=atoi(tim_s1);
				time2=atoi(tim_s2);//将数组转化为数据,,便于计算
				for(j=0;j<2;j++){
                  tim_s1[j]=CHAR.cartime[j+6];
                  tim_s2[j]=char1[i].cartime[j+6]}
				time1=time1+atoi(tim_s1)*60;
				time2=time2+atoi(tim_s2)*60;//算上分钟的秒
							
				for(j=0;j<2;j++){
				tim_s1[j]=CHAR.cartime[j+4];
				tim_s2[j]=char1[i].cartime[j+4];
				}
				time1=time1+atoi(tim_s1)*3600;
				time2=time2+atoi(tim_s2)*3600;//算上时钟的秒
				for(j=0;j<2;j++){
				tim_s1[j]=CHAR.cartime[j+2];	
				tim_s2[j]=char1[i].cartime[j+2];	
				}
				time1=time1+atoi(tim_s1)*3600*24;
				time2=time2+atoi(tim_s2)*3600*24;//算上一天的秒
				time=-time2+time1;			//计算使用时间
				time=time/3600+1;				//这里的time代表小时,因为是按小时收费,所以未满1小时还是加了1
				//返回数据到串口
				sprintf(charge, " %d" , time);
				if(char1[i].carx=='C'){	
									USART_SendString("C");
									}
									else
									{
									USART_SendString("V");		
									}
				USART_SendString("NBR");	
								USART_SendString(":");
								USART_SendString(CHAR.car1);
								USART_SendString(":");			
								USART_SendString(charge);
                              if(char1[i].carx=='C'){
							sprintf(charge, " %.2f" , (time)*FCNBR);
							CNBR--;
												}
							else if(char1[i].carx=='V')
							{
							VNBR--;
							sprintf(charge, " %.2f" , (time)*FVNBR);				
												}
							USART_SendString(":");
							USART_SendString(charge);
                            	qinglin(i);	
				}}}
		else{//这里是判断入库,要先判断不是出库	
	for(i = 1;i<10;i++){
		if(cccc[i]==0){//代表空车位
					if((CHAR.carx=='C')){
					CNBR++;
					}
					else if((CHAR.carx=='V'))
					{
					VNBR++;
					}						
					else{
					USART_SendString("EER");
					}
		cccc[i]=1;//1代表有车占了车位
		charu(i);	
		i=9;	
		}}}}
	else{
			RXOVER = 0;
			USART_SendString("\n");
			USART_SendString("err");
			USART_SendString("\n");
		}}
    USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
}

串口中断

void USART2_IRQHandler(void)
{
	
	uint8_t temp;
	
	if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET){
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);		
		temp = USART_ReceiveData(USART2);
		USART_RXBUF[RXCUNT] = temp;
		RXCUNT++;					//这样会保证每次中断标志位都加一
		if((temp == 'x')||(RXCUNT==22) ){					
			RXCUNT = 0;
			RXOVER = 1;  //接收完成标志位置位
			USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);
										}}}

拆分串口接受数组

void date(){
	CHAR.carx=USART_RXBUF[0];
		for(i=5;i<9;i++){
		CHAR.car1[i-5]=USART_RXBUF[i];
						}
		for(i=10;i<22;i++){
		CHAR.cartime[i-10]=USART_RXBUF[i];
						}}

归纳总结

这个训练项目,主要难度对于我,主要在设计出入库的算法上和对串口接受到的数据进行处理分析,对现在我的是一次不错的锻炼。

你可能感兴趣的:(stm,单片机)