第十二届蓝桥杯嵌入式省赛真题演练——停车计费系统

题目分析

在这里插入图片描述

模块配置、编写

有了第十三届真题的经验,根据题目所给硬件框图,先在cube中创建工程,配置相应的GPIO和定时器,完成pwm输出、LED指示、LCD显示、按键、串口通信五个模块代码编写。
在这里插入图片描述

TIM4作按键模块定时器
在这里插入图片描述
TIM17作信号输出模块定时器
在这里插入图片描述
串口
在这里插入图片描述
按键模块:.c

#include "key.h"

struct KEY_STA key_sta[4] = {0};


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)	//定时器溢出中断回调函数
{
	if(htim->Instance == TIM4)
	{
		key_sta[0].value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		key_sta[1].value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key_sta[2].value = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key_sta[3].value = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
	}
	
	for(uint8_t i = 0;i<4;i++)		//三个状态消抖 
	{
		switch(key_sta[i].step)
		{
			case 0:
			{
				if(key_sta[i].value == 0)
				{
					key_sta[i].step ++;
					
				}
			}
				break;
			
			case 1:
			{
				if(key_sta[i].value == 0)
				{
					key_sta[i].step ++;
					key_sta[i].flag = 1;
				}
				else
				{
					key_sta[i].step = 0;
				}
			}
				break;
			
			case 2:
			{
				if(key_sta[i].value == 1)
				{
					key_sta[i].step = 0;
				}
				
			}
				break;
		}
	}
}


void key_pro()		//按键功能实现函数
{
	if(key_sta[0].flag == 1)
	{
		led_pro(0x80);
		key_sta[0].flag = 0;
	}
	
	if(key_sta[1].flag == 1)
	{
		key_sta[1].flag = 0;
	}
	
	if(key_sta[2].flag == 1)
	{
		key_sta[2].flag = 0;
	}
	
	if(key_sta[3].flag == 1)
	{
		key_sta[3].flag = 0;
	}
}

led模块:

#include "key.h"

void led_pro(uint8_t cho)
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,cho << 8,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

lcd显示模块:

#include "dis.h"

uint8_t view = 0;
uint8_t text[30] = {0};


void dis_pro()		//显示界面函数
{
	if(view == 0)			//界面一
	{
		sprintf((char *)text,"       D a t a");
		LCD_DisplayStringLine(Line1,text);	
	}
	
	if(view == 1)		//界面二
	{
		sprintf((char *)text,"       P a r a");
		LCD_DisplayStringLine(Line1,text);
	}
}

串口通信模块:

#include "n_uart.h"

uint8_t Dat = 0;
uint8_t Re_dat[30] = {0};
uint8_t pointer = 0;


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)		//串口接收中断回调函数
{
	Re_dat[pointer++] = Dat;
	HAL_UART_Receive_IT(huart, &Dat, 1);
}

具体功能实现

看过题目要求后,发现最复杂的就是串口模块的功能:

void uart_pro()		//串口功能实现函数
{
	if(pointer == 22)	
	{
		sscanf((char *)Re_dat,"%4s:%4s:%12s",Type,Num,Time);
		if(0==strcmp((char *)Type,(char *)Type_C))
			C_Num++;
		if(0==strcmp((char *)Type,(char *)Type_V))
			V_Num++;
		
		
			for(uint8_t i = 0;i<8;i++)
			{
				if((0 == strcmp((char *)Type,(char *)tc[i].type)) && (0 == strcmp((char *)Num,(char *)tc[i].num)))		//判断是否已经停入
				{
					stay = ((Time[6]-'0')*10+(Time[7]-'0'))-((tc[i].time[6]-'0')*10+(tc[i].time[7]-'0'));		//计算停车时长
					if(((Time[8]-'0')*10+(Time[9]-'0'))-((tc[i].time[8]-'0')*10+(tc[i].time[9]-'0'))>0)
						stay++;
					if(0==strcmp((char *)Type,(char *)Type_C))		//判断是哪种停车类型
					{
						C_Num -= 2;			//车开出来
						mon = stay * mon_c;		//消费
						
					}
					if(0==strcmp((char *)Type,(char *)Type_V))
					{
						V_Num -= 2 ;
						mon = stay * mon_v;
						
					}
					uint8_t temp[30] = {0};
					sprintf((char *)temp,"%4s:%4s:%2d:%.2f",Type,Num,stay,mon);
					HAL_UART_Transmit(&huart1,temp,strlen((char *)temp),50);		//反馈消费信息
					memset(tc[i].type,0,5);		//车位信息清零
					memset(tc[i].num,0,5);
					memset(tc[i].time,0,13);
					break;
				}
				
				else			//如果没有停过,就将车停进去
				{
					if(S_Num > 0)		//如果还有空位置
					{
						strcpy((char *)tc[i].type,(char *)Type);
					  strcpy((char *)tc[i].num,(char *)Num);
					  strcpy((char *)tc[i].time,(char *)Time);
					break;
					}

				}
			}
		

	}
	else		//如果收到的字符串不正确
	{
		uint8_t temp[30] = {0};
		sprintf((char *)temp,"ERROR");
		HAL_UART_Transmit(&huart1,temp,strlen((char *)temp),50);
	}
	pointer = 0;
	memset(Re_dat,0,30);
}

按键、信号输出模块:

void key_pro()		//按键功能实现函数
{
	if(key_sta[0].flag == 1)		//切换界面
	{
		view ++;
		if(view > 1)
			view = 0;
		LCD_Clear(Black);
		key_sta[0].flag = 0;
	}
	
	if(key_sta[1].flag == 1)			//调整费率
	{
		mon_c += 0.5;
		mon_v += 0.5;
		key_sta[1].flag = 0;
	}
	
	if(key_sta[2].flag == 1)
	{
		mon_c -= 0.5;
		mon_v -= 0.5;
		key_sta[2].flag = 0;
	}
	
	if(key_sta[3].flag == 1)		//信号设置
	{
		if(frq == 0)
		{
			__HAL_TIM_SET_AUTORELOAD(&htim17, 1999);
			__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, 399);
		}
		else
		{
			__HAL_TIM_SET_AUTORELOAD(&htim17, 1999);
			__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1, 0);
		}
		key_sta[3].flag = 0;
	}
}

LCD显示

void dis_pro()		//显示界面函数
{
	if(view == 0)			//界面一
	{
		sprintf((char *)text,"       D a t a");
		LCD_DisplayStringLine(Line1,text);
		sprintf((char *)text,"   C N B R:%d",C_Num);
		LCD_DisplayStringLine(Line4,text);
		sprintf((char *)text,"   V N B R:%d",V_Num);
		LCD_DisplayStringLine(Line6,text);
		S_Num = A_Num - C_Num - V_Num;
		sprintf((char *)text,"   I D L E:%d",S_Num);
		LCD_DisplayStringLine(Line8,text);		
	}
	
	if(view == 1)		//界面二
	{
		sprintf((char *)text,"       P a r a");
		LCD_DisplayStringLine(Line1,text);
		sprintf((char *)text,"   C N B R:%.2f",mon_c);
		LCD_DisplayStringLine(Line4,text);
		sprintf((char *)text,"   V N B R:%.2f",mon_v);
		LCD_DisplayStringLine(Line6,text);

	}
}

工程文件可供参考:
链接:https://pan.baidu.com/s/1J3WGl59Q7vqRDJv5wrBKbw?pwd=7uw5
提取码:7uw5

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值