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

news/2025/4/1 2:40:38/

一、题目概览

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

二、分模块实现

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如果有其他思路请评论!!(*^_^*)


http://www.ppmy.cn/news/1584021.html

相关文章

SpringBoot中WebMvcConfigurer注册多个拦截器(addInterceptors)时的顺序问题(二)

在Spring MVC的拦截器&#xff08;Interceptor&#xff09;中&#xff0c;preHandle、postHandle 和 afterCompletion 这三个方法的执行顺序与整个请求-响应流程密切相关。以下是它们的详细执行顺序和触发时机&#xff1a; 1. 完整执行顺序流程图 客户端请求 → Interceptor1.…

TraeAI结合Proteus实现AI编程并仿真一个复杂工业物联网控制系统的开发(视频)

简介&#xff1a; 本视频聚焦基于国内首个 AI 原生集成开发环境&#xff08;AI IDE&#xff09;的 AI 编程实践。借助提示词&#xff0c;在 Proteus 环境下结合 ESP32 - S3&#xff0c;运用 MicroPython 进行状态机程序设计。展示如何通过在Trae CN人工智能集成编程开发环境&am…

蓝桥杯备考:BFS之马的遍历

这道题我们得知道象棋里的马能怎么走,应该是按日字走的 如图&#xff0c;就这么走&#xff0c;我们按基础的bfs遍历一下标记每个格子的最短的路径就行了&#xff0c;没到达的格子就设置为-1 #include <iostream> #include <queue> #include <cstring> using…

Python与文件——保存文件

1.以下关于Python二维数据的描述中,错误的是()。 A、CSV文件的每一行是一维数据,可以用列表、元组表示。 B、从CSV文件获得数据内容后,可以用replace()来去掉每行最后的换行符。 C、若一个列表变量里的元素都是字符串类型,则可以用join()合成字符串。 D、列表中保存的二维数据,…

MySQL 的 JSON 查询

MySQL 的 JSON 路径格式 MySQL 使用特定的 JSON 路径表达式语法来导航和提取 JSON 文档中的数据 基本结构 MySQL 中的 JSON 路径遵循以下通用格式 $[路径组件]路径组件详解 | 操作符 | 描述 | 示例 | | ----------- | --------- | ----------…

HarmonyOS WebSocket全场景应用开发深度解析

注&#xff1a;适用版本&#xff08;Harmony OS NEXT / 5.0 / API 12 &#xff09; 一、最终效果预览 二、基础代码结构 Entry Component struct ChatApp {State messages: Message[] [] // 所有聊天记录State inputText: string "" // 输入框内容State isCon…

【NLP 48、大语言模型的神秘力量 —— ICL:in context learning】

目录 一、ICL的优势 1.传统做法 2.ICL做法 二、ICL的发展 三、ICL成因的两种看法 1.meta learning 2.Bayesian Inference 四、ICL要点 ① 语言模型的规模 ② 提示词prompt中提供的examples数量和顺序 ③ 提示词prompt的形式&#xff08;format&#xff09; 五、fine-tune VS I…

Go语言中html/template模块详细功能介绍与示例

Go语言的 html/template 模块是专门用于生成安全 HTML 输出的模板引擎&#xff0c;支持自动转义以防止 XSS 攻击。以下是该模块的核心方法及用法示例&#xff1a; 1. 基础模板解析与渲染 template.Parse 和 template.Execute 解析模板字符串并渲染数据。 package mainimport…