上一节我们初步了解了中断的配置、串口的调试以及中断处理子程序的定义,接下来我们就来学习一下具体如何去应用串口中断。
一、真题引入
1.功能概述

2.串口功能




二、环境配置
我们依旧以第四节完成的第12届蓝桥杯节选题为初始环境进行配置,复制出副本改名为USART

1) CubeMX 初始化 USART1
(一配引脚和异步通讯,二配速率、长度等,三配中断允许和优先级);




2) 打开keil,将main.c恢复到两节前的内容
参考原来代码里的全局变量、头文件、函数声明、函数定义进行文件恢复。
这告诉我们编程时及时存档拷贝备份是很重要的!!)
三、函数实现
1.led.h led.c key.c key.h
参考基于STM32G431嵌入式学习笔记——四、LED+KEY+LCD综合练习(基于第12届蓝桥杯显示部分题目)
2.busi.h
在书写头文件前,我们首先要考虑关于停车场我们都需要有什么:
各种基本属性(车、时间、停车位);进车库出车库操作还有一些基本的异常处理函数。
因此我们围绕以上设想进行书写。
(1)一些基本属性的定义
车:车的类型 + 车牌号
时间:年月日时秒分
停车位:车 + 停留时间 + 是否有车占据

(2)相关属性的初始化

(3)相关异常以及状态判断

(4)关于停车场会发生的功能函数

至此busi.h头文件编写完毕,完整代码如下:
//车
typedef struct Car
{
char type[5];
char id[5];
}Car;
//时间
typedef struct Time
{
int year,month,day;
int hour,minute,second;
}Time;
//停车位
typedef struct Parking
{
Car car;
Time time;
char flag;
}Parking;
//停车场有8个位置
#define PARKING_SIZE 8
//车辆信息初始化
Car CarInit(char* type,char* id);
//时间设置
Time TimeInit(int year,int month,int day,int hour,int minute,int second);
//停车场初始化
void ParkingInit(void);
//判断传入字符串格式是否正确
int DataSplit(void);
//判断当前车位是否是空
int IsEmpty(Parking now);
//判断目前的车是进场还是离场(停车场原来就存在则为离场)
int IsExist(Car oldcar,Car newcar);
//车辆进入停车场
int ParkIn(Parking *park,Car car,Time enter);
//车辆离开停车场
float ParkOut(Parking *park,Car car,Time leave);
//清空某车位信息
void ClearPark(Parking *park,int location);
//串口通信函数
void park_proc(Parking *park,Car car,Time time);
3.busi.c
(1)多个文件都会使用的全局变量定义
当我们想让某个全局变量在同工程不同文件下起到相同作用,则需借助extern来修饰:

(2)仅在该文件会使用的全局变量定义

(3)相关属性的初始化
其中strcpy用到了#include "string.h"的头文件

(4)相关异常以及状态判断
①字符串格式校验
我们会对字符串进行分割拆解,并对分割出来的每一个字符串进行类型的校验。
这里用到了**sscanf( )函数,来自#include “sdtio.h”**的头文件
常见用法如下:
那么这一长长的字符串是从哪里来的呢?我们通过题目可以知道车辆信息是由串口输入的,因此我们需要设置一些与串口通信有关的变量,写入usart.c文件中:

其中RxLen、TxLen分别为接收信息、发送信息的字符串长度,其定义应在usart.h文件中进行宏定义;
且在刚刚定义的这几个变量我们是会在多个文件中去使用的,因此我们不妨将其在头文件中再次定义(添加extern是代表这个全局变量在每个文件中出现的时候代表的是相同的变量)
如果将extern变量写入某头文件,这样如果我们想在多个.c文件中使用该变量,仅需在对应的文件开头添加#include "某某.h"就好
具体结果如下:

这时我们便可以在busi.c中调用该头文件,去使用这些串口通信变量(顺便将可能会即将用到的头文件也加入):

接下来我们就书写函数内容,大体思路就是“分割字符串,匹配字符串,不合要求就返回0,并向串口发送端buffer传入错误提示信息;完全匹配就返回1”

②判断车位是否为空 ③判断当前车是否与现停的车相同
(5)关于停车场会发生的功能函数
①进入停车场

②离开停车场 + 清除车位数据
继续跟在上面的函数之后书写就好
//车辆离开停车场
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

本文详细介绍如何在STM32G431平台上利用串口中断进行编程,包括环境配置、USART初始化、函数实现,以及基于串口通信实现的停车场管理功能,如车位判断、车辆进出、费用计算等。
最低0.47元/天 解锁文章
1万+





