STM32CubeMX配置串口DMA接发数据及数据解析
最近做个小项目对串口数据传输和解析的稳定性都有要求,记录下来方便学习参考
串口初始化配置
我们使用STM32CubeMX配置串口初始化代码,该代码和配置基于stm32l475ret6芯片开发板,其他芯片和开发板也适用,改配置即可。
CubeMX配置
由于是使用类型的笔记,所以不涉及DMA原理之类的内容。
项目总体配置
首先是配置RCC 、SYS。这部分配置都是很基本的操作,配置完成的截图如下。
RCC时钟源设置为外部低速时钟
SYS配置选择Serial Wire
串口参数配置
点击USART1
设置为异步通信
点击Parameter Setting
设置为9600波特率,数据长度8位,偶校验,停止位1,接收发送模式(根据模块的通信协议设置)
DMA&NVIC
- 依次点击DMA Setting→Add→Select→USART1_RX/USART1_TX,DMA配置完整界面如下
- 开启中断
项目其他配置
- 系统时钟频率、文件名、存储位置之类的基础配置。
- 系统时钟频率配置为50MHz方便计算
项目名,项目位置根据自己需要配置
配置完成后直接点< GENERATE CODE >生成。
代码
串口初始化
- main.c
添加用户串口初始化函数,参数为模块对应串口的句柄
- lora.c
用户串口初始化函数
串口中断数据处理
完成串口初始化后,当串口数据传输结束进入空闲状态时就会调用空闲中断函数进行数据处理,用户只要在串口中断加入自己的数据处理函数即可
- stm32l4xx_it.c(简称it.c)
在 it.c 内可以找到串口对应的中断处理函数,在里面调用用户的数据处理函数即可。
如下图中Lora_Rec_Process(&huart1);
- lora.c
这里面是用户串口中断数据处理调用的函数的主体。
在这里只列出数据接收部分函数,把串口数据接收到接收数组中,并进行后续的数据校验,数据处理等流程。
- 上位机发送端协议解析代码参考
int size;
try {
// 构建数据部分(包括字符 '2' 和两个时间戳)
byte[] data = new byte[10]; // 数据部分长度为 10 字节
data[0] = 0x09; // 数据部分长度
data[1] = 0x32; // 字符 '2' 的字节表示
// 将时间戳转换为字节数组
byte[] BeginTimeStampBytes = ByteBuffer.allocate(4).putInt((int) BegintimeStamp).array();
byte[] EndTimeStampBytes = ByteBuffer.allocate(4).putInt((int) EndtimeStamp).array();
// 将时间戳的字节数组复制到数据数组中
System.arraycopy(BeginTimeStampBytes, 0, data, 2, 4); // 从索引 2 开始复制,复制4个字节
System.arraycopy(EndTimeStampBytes, 0, data, 6, 4); // 从索引 6 开始复制,复制4个字节
// 计算校验和
byte checksum = calculateChecksum(data);
// 构建完整的数据帧(包括帧头和校验和)
byte[] fullFrame = new byte[data.length + 4]; // 数据部分长度 + 帧头长度 + 校验和长度
fullFrame[0] = (byte) 0x5A; // 帧头第一个字节
fullFrame[1] = (byte) 0x5A; // 帧头第二个字节
fullFrame[2] = (byte) 0x45; // 帧头第三个字节
System.arraycopy(data, 0, fullFrame, 3, data.length); // 复制数据部分
fullFrame[data.length + 4] = checksum; // 最后一个字节为校验和
// 发送完整的数据帧
mOutputStream.write(fullFrame);
} catch (IOException e) {
e.printStackTrace();
}