当前位置: 首页 > news >正文

蓝桥杯嵌入式第十二届程序设计题

一、题目概览

设计一个小型停车计费系统

二、分模块实现

1、LCD

void disp_proc()
{
	if(view==0)
	{
		char text[30];
		sprintf(text,"       Data");
		LCD_DisplayStringLine(Line2,(uint8_t *)text);
		
		sprintf(text,"   CNBR:%d           ",Cnum);
		LCD_DisplayStringLine(Line4,(uint8_t *)text);    
		sprintf(text,"   VNBR:%d           ",Vnum);
		LCD_DisplayStringLine(Line6,(uint8_t *)text);
		sprintf(text,"   IDLE:%d           ",idle-Cnum-Vnum);
		LCD_DisplayStringLine(Line8,(uint8_t *)text);
	}
	if(view==1)
	{
		char text[30];
		sprintf(text,"       Para");
		LCD_DisplayStringLine(Line2,(uint8_t *)text);
		
		sprintf(text,"   CNBR:%.2lf        ",Crate);
		LCD_DisplayStringLine(Line4,(uint8_t *)text);
		sprintf(text,"   VNBR:%.2lf        ",Vrate);
		LCD_DisplayStringLine(Line6,(uint8_t *)text);
	}
}

2、按键

Crate和Vrate分别是CNBR类型和VNBR类型停车的费率,按按键B3的减少我没有设置下限(仔细看了题目没要求),而且设置下限为零的话重新开始加的话两个费率就相等了。

void key_proc()
{
	if(key[0].single_flag==1)//B1
	{
		view=!view;
		LCD_Clear(Black);
		key[0].single_flag=0;
	}
	if(key[1].single_flag==1)//B2
	{
		if(view==1)
		{
			Crate+=0.5;
			Vrate+=0.5;
		}
		key[1].single_flag=0;
	}
	if(key[2].single_flag==1)//B3
	{
		if(view==1)
		{
			Crate-=0.5;
			Vrate-=0.5;
		}
		key[2].single_flag=0;
	}
	if(key[3].single_flag==1)//B4
	{
		state=!state;
		if(state==1)
		{
			HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
			__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,(20/100)*(80000000/80/2000));
			LED_state|=0x02;LED_Disp(LED_state);
		}
		else
		{
			HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
			LED_state&=0xFD;LED_Disp(LED_state);
		}
		key[3].single_flag=0;
	}
}

3、PA7脉冲输出

 

4、串口通信(重点)

串口通信的基础代码我学习的是B站这个uart串口通信(完结)_哔哩哔哩_bilibili

 这个题目最关键的部分就是串口接收数据的处理,即对时间的解析算出停车时间

自定义的变量:

extern struct keys key[];
extern uint frq;
extern float duty;
bool view=0;
bool cnbr_flag=0;
bool vnbr_flag=0;

extern char rxdata[];
extern uint8_t rxdat;
extern int rx_point;//接收位指针

struct CarInfo
{
	char car_type[5];
	char car_num[5];
	char car_time[15];
}CNBRnum[10],VNBRnum[10];
int Cnum=0;
int Vnum=0;
int idle=8;
double Crate=3.50;
double Vrate=2.00;

uchar pa7_duty[2]={0,20};
uchar state=0;	//PA7端口输出状态
uchar LED_state=0x01;

// 定义结构体用于保存解析的时间  
typedef struct {  
    uint8_t year;  
    uint8_t month;  
    uint8_t day;  
    uint8_t hour;  
    uint8_t minute;  
} DateTime; 

void key_proc(void);
void disp_proc(void);
void uart_rx_proc(void);
void parse_time(char *time_str,DateTime *dt);
void calculate_time_difference(DateTime *start, DateTime *end, int *hours, int *minutes);

自定义的两个处理时间的函数: 

// 解析时间字符串
void parse_time(char *time_str,DateTime *dt)
{
	dt->year=2000+(time_str[0]-'0')*10+(time_str[1]-'0');
	dt->month=(time_str[2]-'0')*10+(time_str[3]-'0');
	dt->day=(time_str[4]-'0')*10+(time_str[5]-'0');
	dt->hour=(time_str[6]-'0')*10+(time_str[7]-'0');
	dt->minute=(time_str[8]-'0')*10+(time_str[9]-'0');
}
// 计算两个时间之间的差值  
void calculate_time_difference(DateTime *start, DateTime *end, int *hours, int *minutes) {  
    // 简化的差值计算,假设输入是有效的  
    int total_start_minutes = start->year * 525600 + start->month * 43800 + start->day * 1440 + start->hour * 60 + start->minute; // 1年=525600分钟  
    int total_end_minutes = end->year * 525600 + end->month * 43800 + end->day * 1440 + end->hour * 60 + end->minute;  

    int diff_minutes = total_end_minutes - total_start_minutes;  
    *hours = diff_minutes / 60;  
    *minutes = diff_minutes % 60;  
}  

串口接收数据的处理函数: 

void uart_rx_proc()
{
	if(rx_point>0)
	{
		if(rx_point==22)//接收的字符串定长为22
		{
			if(rxdata[0]=='C')//开头字母判断停车类型
			{
				sscanf(rxdata,"%4s:%4s:%12s",CNBRnum[Cnum].car_type,CNBRnum[Cnum].car_num,CNBRnum[Cnum].car_time);
				for(int i=0;i<Cnum;i++)
				{
					if(strcmp(CNBRnum[i].car_num,CNBRnum[Cnum].car_num)==0)//能匹配到一样的车辆编号说明这是出停车场的信息,反之是入停车库
						{
							DateTime start_time,end_time;
							parse_time(CNBRnum[i].car_time,&start_time);	//解析时间字符串,拆分成时、分、秒
							parse_time(CNBRnum[Cnum].car_time,&end_time);
							
							int hours,minutes;
							calculate_time_difference(&start_time,&end_time,&hours,&minutes);	//计算时间差
							if(minutes>0)hours+=1;
							double cost=Crate*hours;
							//串口输出计费信息
							char temp[30];
							sprintf(temp,"CNBR:%4s:%d:%.2lf\r\n",CNBRnum[i].car_num,hours,cost);
							HAL_UART_Transmit(&huart1,(uint8_t *)temp,strlen(temp),50);							
							Cnum-=1;
							
							for(int j=i;j<Cnum;j++) //前移
							{
								strncpy(CNBRnum[j].car_num,CNBRnum[j+1].car_num,strlen(CNBRnum[j].car_num));
								strncpy(CNBRnum[j].car_time,CNBRnum[j+1].car_time,strlen(CNBRnum[j].car_time));
								strncpy(CNBRnum[j].car_type,CNBRnum[j+1].car_type,strlen(CNBRnum[j].car_type));							
							}
							
							cnbr_flag = 1;
							break;
						}
				}
				if(cnbr_flag == 0)	//入车库
				{
					Cnum++;
				}
				cnbr_flag = 0;
			}
			if(rxdata[0]=='V')
			{
				sscanf(rxdata,"%4s:%4s:%12s",VNBRnum[Vnum].car_type,VNBRnum[Vnum].car_num,VNBRnum[Vnum].car_time);
				for(int i=0;i<Vnum;i++)
				{
					if(strcmp(VNBRnum[i].car_num,VNBRnum[Vnum].car_num)==0)
						{
							DateTime start_time,end_time;
							parse_time(VNBRnum[i].car_time,&start_time);
							parse_time(VNBRnum[Vnum].car_time,&end_time);
							
							int hours,minutes;
							calculate_time_difference(&start_time,&end_time,&hours,&minutes);
							if(minutes>0)hours+=1;
							double cost=Vrate*hours;
							
							char temp[30];
							sprintf(temp,"VNBR:%4s:%d:%.2lf\r\n",VNBRnum[i].car_num,hours,cost);
							HAL_UART_Transmit(&huart1,(uint8_t *)temp,strlen(temp),50);	
							Vnum-=1;
							
							for(int j=i;j<Vnum;j++) //前移
							{
								strncpy(VNBRnum[j].car_num,VNBRnum[j+1].car_num,strlen(VNBRnum[j].car_num));
								strncpy(VNBRnum[j].car_time,VNBRnum[j+1].car_time,strlen(VNBRnum[j].car_time));
								strncpy(VNBRnum[j].car_type,VNBRnum[j+1].car_type,strlen(VNBRnum[j].car_type));							
							}
							
							vnbr_flag = 1;
							break;
						}
				}
				if(vnbr_flag == 0)//入库
				{
					Vnum++;
				}
				vnbr_flag = 0;	
			}
			idle = 8-Cnum-Vnum;
			if(idle>0){LED_state|=0x01;LED_Disp(LED_state);}
			else{LED_state&=0xFE;LED_Disp(LED_state);}
		}
		else
		{
			char temp[20];
			sprintf(temp,"Error\n");
			HAL_UART_Transmit(&huart1,(uint8_t *)temp,strlen(temp),50);
		}
		rx_point=0;memset(rxdata,0,30);
	}
}

5、LED指示灯

LED1:(我写在了串口接收数据处理的函数里)

 

LED2: (写在了控制按键B3里面)

6、main

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_TIM2_Init();
  MX_USART1_UART_Init();
  MX_TIM17_Init();
  /* USER CODE BEGIN 2 */
	LCD_Init();
	LED_Disp(0x00);
	
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	
	HAL_TIM_Base_Start_IT(&htim2);
	
	HAL_UART_Receive_IT(&huart1,&rxdat,1);
	
  /* USER CODE END 2 */
                                                                    
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(state == 0)
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
		LED_Disp(LED_state);
		
		if(rx_point!=0)            //防止接收不完整问题
		{
			int temp=rx_point;
			HAL_Delay(1);
			if(temp==rx_point) uart_rx_proc();
		}
		
		key_proc();
		disp_proc();
  }
  /* USER CODE END 3 */
}

三、总结

我使用的是数组的方式存储车辆信息,有车出停车场的情况我的思路是后面的车位‘往前移’,补空位,感觉这个方法有点笨笨的(T_T),so如果有其他思路请评论!!(*^_^*)

相关文章:

  • 海康gdb流程
  • 【算法题讲解】45. 跳跃游戏 II
  • 如何选择适合你的美颜SDK?人脸美型功能对比与应用场景分析
  • C语言中的位域:节省内存的标志位管理技术
  • CTF类题目复现总结-[MRCTF2020]ezmisc 1
  • 交流电机类型及其控制技术
  • 淘宝商品数据清洗实战:从复杂JSON到结构化数据库(附Python脚本)
  • LeeCode 434. 字符串中的单词数
  • Spring Initializr搭建spring boot项目
  • 软件工程面试题(七)
  • 格雷码和汉明码的详细总结
  • Linux中安装宝塔面板
  • vcruntime140.dll丢失导致程序无法运行?八种vcruntime140高效修复方案详解
  • 记录一次交易耗时有毛刺TDSQL数据库排查过程
  • 生物化学笔记:医学免疫学原理08 细胞因子+细胞因子的种类+细胞因子与疾病
  • 【网络】Socket套接字
  • 地图项目入手学习
  • SQL 复杂查询和性能优化
  • 2025美国网络专线国内服务商推荐
  • Unity中实现UI的质感和圆角
  • 男女宾馆做爰视频网站/友情链接代码模板
  • 襄阳网络公司 网站建设/百度指数查询官网大数据
  • 湛江北京网站建设/厦门人才网个人会员登录
  • 购物网站代码/永久免费crm客户管理系统
  • 怀柔谁会网站开发/长沙seo排名优化公司
  • 一个主机放多个网站/友谊平台