目录

实验要求:

实验思路:

核心代码:

(1)主函数

(2)lcd显示

(3)按键函数

(4)LED显示函数

(5)业务处理函数

(6)PWM函数

实验结果:

思考或体会


实验要求:

1) 设计一个停车计费系统,能够完成费率设置、费用计算等功能。

2) 使用串口(USART获取车辆进、出停车场信息和时间,并能够输出计费信息。

3) 使用按键完成费率设置、调整功能。

4) 按照显示要求,通过 LCD 显示停车状态、费率参数。

5) 通过 PA7(PWM 输出固定频率和占空比的脉冲信号或持续低电平。

6) 使用 LED 指示灯完成相关指示功能。

实验思路:

1.涉及到串口中断的相关函数,在CubeMX中也需要相关配置。

2.按键是为LED、LCD服务的,因此最后书写按键状态切换的逻辑。

3.LCD屏幕一共两个屏幕界面,因此要书写两段LCD输出的代码。且板子上电后就有内容显示,默认处于车位显示界面,因此可以首先书写该屏幕的内容保证初始化没问题。

4.PWM输出需要设置时钟,以及降频分频。

5.LED在本题中用到了两处:停车位、PWM状态

核心代码:

(1)主函数

int main(void)

{

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* Configure the system clock */

SystemClock_Config();

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_USART1_UART_Init();

MX_TIM3_Init();

/* Infinite loop */

/* USER CODE BEGIN WHILE */

LCD_Init();//LCD初始化

control_led(LEDALL,OFF);//关闭所有LED灯

ParkingInit();//停车场初始化

HAL_UART_Receive_IT(&huart1, (uint8_t *)usart_rx,RxLen);//接收一次中断

LCD_Clear(Black);//清屏

while (1)

{

lcd_proc();

key_proc();

led_proc();

busi_proc();

pwm_proc();

}

}

(2)lcd显示

void lcd_proc()

{

if(lcd_update_flag==1)//为1时提醒我们要更新lcd了

{

lcd_update_flag=0;

// LCD_Clear(Black);

LCD_SetBackColor(Black);

LCD_SetTextColor(White);

if(lcd_flag == 1)//车位显示界面

{

LCD_DisplayStringLine(Line2,(unsigned char *)"       Data         ");

/*

sprintf函数

用于将我们本应该直接格式化输出的语句内容存储至字符串

位于stdio.h中

*/

sprintf(str,"   CNBR:%d           ",car1);//第四行即将显示的内容

LCD_DisplayStringLine(Line4,(unsigned char *)str);

sprintf(str,"   VNBR:%d           ",car2);//第六行即将显示的内容

LCD_DisplayStringLine(Line6,(unsigned char *)str);

sprintf(str,"   IDLE:%d           ",idle);//第八行即将显示的内容

LCD_DisplayStringLine(Line8,(unsigned char *)str);

}

else//费率设置界面

{

LCD_DisplayStringLine(Line2,(unsigned char *)"       Para         ");

sprintf(str,"   CNBR:%.2f        ",cnbr);

LCD_DisplayStringLine(Line4,(unsigned char *)str);

sprintf(str,"   VNBR:%.2f        ",vnbr);

LCD_DisplayStringLine(Line6,(unsigned char *)str);

LCD_DisplayStringLine(Line8,(unsigned char *)"                    ");

}

}

}

(3)按键函数

void key_proc(void)

{

char value = key_scan();

switch(value)

{

case 1:

/*切换LCD显示屏界面的操作*/

lcd_flag = (lcd_flag == 1 ? 0 : 1);

lcd_update_flag=1;

break;

case 2:

/*CNBR、VNBR费率增加0.5元*/

cnbr += 0.5f;

vnbr += 0.5f;

lcd_update_flag=1;

break;

case 3:

/*CNBR、VNBR费率减少0.5元*/

cnbr -= 0.5f;

vnbr -= 0.5f;

lcd_update_flag=1;

break;

case 4:

/*两种频率输出状态*/

pwm_flag = (pwm_flag == 1 ? 0 : 1);

break;

}

}

(4)LED显示函数

void led_proc(void)

{

if(idle>0)//有车位

{

control_led(LED1,ON);//LED1亮

}

else

{

control_led(LED1,OFF);

}

if(pwm_flag==1)//持续低电平

control_led(LED2,OFF);

else

control_led(LED2,ON);

}

(5)业务处理函数

void busi_proc(void)

{

if(RxEndFlag==1)//串口收到信息则发生中断

{

RxEndFlag = 0;

if(DataSplit())//若传入分割后的字符串合法

{

//初始化结构体

Car car = CarInit(type,id);

Time time = TimeInit(year,month,day,hour,minute,second);

//流程处理

park_proc(park,car,time);

}

if(lcd_flag ==1)//当前是停车信息界面,则需要更新数值

{

lcd_update_flag =1;//lcd屏幕内容要更新了

}

//接收串口传来的信息,然后中断

HAL_UART_Receive_IT(&huart1,(uint8_t*)usart_rx,RxLen);

}

}

(6)PWM函数

void pwm_proc(void)

{

if(pwm_flag)//低电平

{

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);

__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,0);//占空比0

HAL_Delay(5);

}

else//高电平

{

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);

__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,100);//占空比100/500=20%

HAL_Delay(5);

}

}

(7)其他函数(与停车场相关函数位于busi.c中)

//车辆信息初始化

Car CarInit(char* type,char* id)

{

Car car;

strcpy(car.type,type);

strcpy(car.id,id);

return car;

}

//时间设置

Time TimeInit(int year,int month,int day,int hour,int minute,int second)

{

Time time;

time.year = year;time.month = month;time.day = day;

time.hour = hour;time.minute = minute;time.second = second;

return time;

}

//停车场初始化

void ParkingInit(void)

{

int i=0;

for(i=0;i<PARKING_SIZE;i++)

{

Car car = CarInit("","");

Time time = TimeInit(0,0,0,0,0,0);

park[i].car = car;

park[i].time = time;

park[i].flag = 1;//1为可以停车,0为不能停车

}

}

//判断传入字符串格式是否正确

int DataSplit(void)

{

/*分割数据:数据来自uart的接收端*/

sscanf((char *)usart_rx,"%4s:%4s:%2d%2d%2d%2d%2d%2d",type,id,&year,&month,&day,&hour,&minute,&second);

/*清空buffer*/

memset(usart_rx,0,sizeof(usart_rx));

/*字符校验*/

//两种车的类型都不属于

if(strcmp(type,"CNBR")!=0 && strcmp(type,"VNBR")!=0)

{

//错误提示给usart发送端

sprintf(usart_tx,"Type Match Error\n");

HAL_UART_Transmit(&huart1,(unsigned char *)usart_tx,strlen(usart_tx),TxLen);

return 0;

}

//时间书写有问题

else if(month>12||day>31||hour>24||minute>60||second>60)

{

sprintf(usart_tx,"Time Format Error\n");

HAL_UART_Transmit(&huart1,(unsigned char *)usart_tx,strlen(usart_tx),TxLen);

return 0;

}

return 1;//正确则返回1

}

//判断当前车位是否是空

int IsEmpty(Parking now)

{

return now.flag;

}

//判断目前的车是进场还是离场(停车场原来就存在则为离场)

int IsExist(Car oldcar,Car newcar)

{

if(strcmp(oldcar.id,newcar.id)==0 && strcmp(oldcar.type,newcar.type)==0)

{

return 1;

}

return 0;

}

//车辆进入停车场

int ParkIn(Parking *park,Car car,Time enter)

{

int i=0;

if(idle==0)//没有空闲车位

{

return 0;

}

for(i=0;i<PARKING_SIZE;i++)

{

if(IsEmpty(park[i]))

{

park[i].car = car;

park[i].time = enter;

park[i].flag = 0;

idle--;

if(strcmp(car.type,"CNBR") == 0)

{

car1++;

}

if(strcmp(car.type,"VNBR")==0)

{

car2++;

}

if(idle == 0)

{

control_led(LED1,OFF);

}

else

{

control_led(LED1,ON);

}

return 1;

}

}

return 0;

}

//车辆离开停车场

float ParkOut(Parking *park,Car car,Time leave)

{

int i,ptime1,ptime2;

i = ptime1 = ptime2 = 0;

float price = 0;

Car oldcar;

Time oldtime;

for(i=0;i<8;i++)

{

oldcar = park[i].car;

oldtime = park[i].time;

//进入if循环则说明是要从这个位置离开停车场

if(IsExist(oldcar,car))

{

//判断时间是否合法

ptime1 = (leave.year - oldtime.year)*365*24 +

(leave.month - oldtime.month)*30*24 +

(leave.day - oldtime.day)*24 +

(leave.hour - oldtime.hour)*1;

ptime2 = (leave.minute - oldtime.minute)*60 +

(leave.second - oldtime.second);

//进入if说明时间不合法

if(ptime1<0 || ptime2<0)

{

return -2;//time error

}

else

{

idle++;

if(strcmp(car.type,"CNBR")==0)

{

price = cnbr;

car1--;

}

if(strcmp(car.type,"VNBR")==0)

{

price = vnbr;

car2--;

}

ClearPark(park,i);

ParkTime = ptime2>0 ? (ptime1+1) : ptime1;

SumMoney = (float)price*ParkTime;

return SumMoney;

}

}

}

return -1;//没有匹配的车位,说明这辆车原本就不在车库里

}

//清空某车位信息

void ClearPark(Parking *park,int location)

{

Car car;

Time time;

car=CarInit("","");

time = TimeInit(0,0,0,0,0,0);

park[location].car = car;

park[location].time = time;

park[location].flag = 1;

return ;

}

//串口通信函数

void park_proc(Parking *park,Car car,Time time)

{

SumMoney = ParkOut(park, car, time);

//没有匹配,就尝试能不能进入停车场

if(SumMoney==-1.0)

{

if(ParkIn(park,car,time))

{

sprintf(usart_tx,"Success Parking Car!\n");

HAL_UART_Transmit(&huart1,(unsigned char*)usart_tx,strlen(usart_tx),TxLen);

}

else

{

sprintf(usart_tx,"Error! Parking is full\n");

HAL_UART_Transmit(&huart1,(unsigned char*)usart_tx,strlen(usart_tx),TxLen);

}

}

//时间非法

if(SumMoney==-2.0)

{

sprintf(usart_tx,"Time Logic Error ! \n");

HAL_UART_Transmit(&huart1,(unsigned char*)usart_tx,strlen(usart_tx),TxLen);

}

//出库成功

if(SumMoney>=0)

{

sprintf(usart_tx,"%s:%s:%d:%.2f\n",car.type,car.id,ParkTime,SumMoney);

HAL_UART_Transmit(&huart1,(unsigned char*)usart_tx,strlen(usart_tx),TxLen);

}

}

实验结果:

思考或体会

1. 实验的初始化很重要,CubeMX配置一定不能出现差错,特别是配置时钟时频率设置出错会造成很大影响。

2.题目需要我们书写许多额外的头文件和.c文件,例如在书写停车场业务头文件前,我们首先要考虑关于停车场我们都需要有什么:

各种基本属性(车、时间、停车位);进车库出车库操作还有一些基本的异常处理函数。我们就需要围绕以上设想进行书写

3.串口中断一定要在进入while循环前首先调用一次接收函数,否则无法进行Callback回调,造成通讯失败。

4.模块之间关联多用一些状态变量,实现多模块的同步协调通信。

第12届嵌入式蓝桥杯真题-停车场管理系统的设计与实现相关推荐

  1. 第九届蓝桥杯真题解析JavaC组

    第九届蓝桥杯真题解析JavaC组 文章目录 ***第九届蓝桥杯真题解析JavaC组*** 前言 A.哪天回家 B.猴子分香蕉 C.字母阵列 D.第几个幸运数 E.书号验证 F.打印大X G.缩位求和 ...

  2. 第六届蓝桥杯真题总结

    第六届蓝桥杯真题总结 第一题:奖券数目 有些人很迷信数字,比如带"4"的数字,认为和"死"谐音,就觉得不吉利.虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求 ...

  3. 2016年第七届蓝桥杯真题解析JavaC组

    相关题目: 2016年第七届蓝桥杯真题解析JavaB组 2016年第七届蓝桥杯真题解析JavaC组 2017年第八届蓝桥杯真题解析JavaB组 2017年第八届蓝桥杯真题解析JavaC组 2018年第 ...

  4. 第十届蓝桥杯c语言试题,第十届蓝桥杯真题编程题1-7解析(高级组).pdf

    scratch 少儿编程第十届蓝桥杯真题 7 大家好 ~今天我们来讲解 scratch 蓝桥杯第十届编程大题的第七道题. 同样,这道题也是非常有难度的一道题.一起来看一下吧 解析: 女孩的程序 1.在 ...

  5. 第五届蓝桥杯真题解析【JavaC组】

    第五届蓝桥杯真题解析[JavaC组] 业精于勤,荒于嬉:行成于思,毁于随.--韩愈 文章目录 ***第五届蓝桥杯真题解析[JavaC组]*** 前言 A:猜年龄 B:等额本金 C:猜字母 D:大衍数列 ...

  6. 【蓝桥杯真题】16天冲刺 Python

    距离比赛很快了,希望和我一起准备的PY党能更加熟练的掌握Python! 1.距离和(模拟赛填空题) 问题描述: 两个字母之间的距离定义为它们在字母表中位置的距离.例如 A和 C 的距离为 2,L 和  ...

  7. # 2014年蓝桥杯真题CC++B组

    2014年蓝桥杯真题C/C++B组 1.啤酒和饮料 题目描述 啤酒每罐2.3元,饮料每罐1.9元,小明买了若干啤酒和饮料,一共花了82.3元. 我们还知道她买的啤酒比饮料的数量多,请你计算他买了几罐啤 ...

  8. 蓝桥杯python省赛冲刺篇2——常用算法的详细解析及对应蓝桥杯真题:打表模拟法、递推递归法、枚举法、贪心算法、差分与前缀和

    注意:加了题目链接 目录 注意:加了题目链接 一.打表模拟法 介绍 1. 算式问题 题目描述 解析与代码演示 2. 求值 题目描述 解析与代码演示 3. 既约分数 题目描述 解析与代码演示 4. 天干 ...

  9. 蓝桥杯真题2017-2021

    刷完近几年真题,感觉理解完之后,拿奖问题不大,本人这次获得2022年蓝桥杯javaB组省一,以下是历年javaB组省赛题目. 文章目录 2017年真题 一.购物单 二.纸牌三角形 三.承压计算 四.魔 ...

最新文章

  1. linux shell 删除7天前的文件
  2. 遍历系统的所有ObjectType和TypeIndex
  3. clcikhouse Code: 1000. DB::Exception: File not found
  4. ps ico插件_Photoshop 2020特别版 内置多款实用插件
  5. java 字符串数组连接
  6. 大数据WEB阶段(十一)Ajax、URL编码
  7. Mac上IDA报错/:Permission denied Please specify another file path for the database
  8. respondsToSelector
  9. 「ubuntu」在Ubuntu Server 16.04 LTS下安装VMware Tools(转)
  10. EnableViewState详细分析
  11. 简单工厂,工厂方法,抽象工厂思想-手机时代的变迁
  12. 从“洗脸巾”到“湿厕纸”,生活用纸的品类扩张之路
  13. 探索智慧医院落地新方案!OFweek 2019医疗物联网大会成功举办
  14. 怎么进入服务器修改跳转域名,域名怎么跳转到别的网站
  15. 解决:Field xxMapper in xx.service.impl.xxServiceImpl required a bean of type 'xx.mapper.xxMapper'...
  16. 查看修改qcow2文件
  17. 怎么使用大疆无人机建模?
  18. 【Android】RXAndroid
  19. 计算机的用途英语作文带翻译,关于计算机的英文作文带翻译
  20. agv ti 毫米波雷达_一种基于毫米波雷达的AGV小车的制作方法

热门文章

  1. Mybatis使用小札
  2. idea 调用c#接口_c# api接口开发
  3. app沙箱宝支付接口怎么测_支付宝沙箱测试DEMO实践
  4. 基于matlab蓝牙跳频系统,基于Matlab软件的蓝牙跳频改进算法
  5. UICC 之 USIM 详解全系列——常用命令详解与实例说明
  6. iOS中Tager-Action 应用举例实现 高内聚低耦合
  7. 搭建RobotFramework环境(Windows)
  8. 编译文件时报错:错误: 编码GBK的不可映射字符
  9. 5 单选题 计算机病毒是指( ),计算机病毒指的是事业单位考试题库考点高频试题:1、单选题秦汉(5)...
  10. 【题解】【AcWing】1609. 前序和后序遍历