文章目录
前言
在 STM32 通信协议中,读取类指令(CID1=46H)是最基础的交互功能。本文以 读取温度(CID2=01H) 和 读取温度保护(CID2=02H) 为例,演示如何将协议帧中的字节流转换为实际物理量,并实现与上位机的双向通信
本项目所有功能效果展示视频链接
一、读取温度指令:从硬件到协议的完整链路
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
1.指令帧构造
- 上位机发送帧
字段 | 值 | 说明 |
---|---|---|
SOI | 0x7E | 起始标志 |
CID1 | 0x46 | 读取参数主功能码 |
CID2 | 0x01 | 温度子功能码 |
LENGTH | 0x00 | INFO 长度(无请求数据) |
INFO | - | 无 |
CHKSUM | XX | CRC8校验码(计算范围:CID1 到 INFO) |
EOI | 0xEF | 结束标志 |
计算 CHKSUM 示例:
计算范围为 46 01 00,CRC8 校验值为 0xEE, 则指令帧为 7E 46 01 00 EE EF。
- STM32响应帧
字段 | 值 | 说明 |
---|---|---|
SOI | 0x7E | - |
CID1 | 0x46 | - |
CID2 | 0x01 | - |
LENGTH | 0x02 | INFO 长度为 2 字节(温度值) |
INFO | 0x00 F6 | 温度值(合并为 0x00F6=246,单位:0.1℃→24.6℃) |
CHKSUM | 8F | CRC8校验码(计算范围:CID1 到 INFO) |
EOI | 0xEF | - |
2.代码实现
- 温度值解析函数: 温度传感器采用DS18B20
void Get_TempData(void)
{
float Temp;
Temp = DS18B20_Get_Temp();
ADC_DataInfo.Temp_Info = (uint16_t)Temp;
//Para_Buf[71] 为读取量的偏移设置 、Para_Buf[64]为读取量的偏移量
if(Para_Buf[71] == 0x00)
{
ADC_DataInfo.Temp_Info = ADC_DataInfo.Temp_Info + Para_Buf[64] ; //校准值
}
else if(Para_Buf[71] == 0x01)
{
ADC_DataInfo.Temp_Info = 250;
}
}
- 指令处理逻辑
/***********************************************************************/
// 函数名称:SendTemptData
// 函数描述:温度数据上传到上位机
// 输入参数:无
// 输出参数:无
// 其 他:无
/***********************************************************************/
void SendTempData(void)
{
ShareBuf[0] = 0x7E; // 起始符
ShareBuf[1] = 0x46; // CID1
ShareBuf[2] = 0x01; // RNT
ShareBuf[3] = 0x02; // Len
ShareBuf[4] = ADC_DataInfo.Temp_Info>>8 ; // Data
ShareBuf[5] = ADC_DataInfo.Temp_Info & 0x00FF; // Data
ShareBuf[6] = CalculateCRC8(&ShareBuf[1], ShareBuf[3] + 3);; // CRC
ShareBuf[7] = 0xEF; // 结束符
Usart1_Transmitter(ShareBuf, ShareBuf[3] + 6); // 发送数据
}
3.调试工具验证
- 串口调试助手操作
发送原始帧:7E 46 01 00 EE EF
接收响应帧:7E 46 01 02 00 F6 8F EF,解析为 24.6℃。
二、读取温度参数指令
1. 指令帧与响应帧格式
- 上位机发送帧
与温度指令类似,仅 CID2=02H:
7E 46 02 00 XX EF(XX 为 CHKSUM)。 - STM32 响应帧
字段 | 值 | 说明 |
---|---|---|
LENGTH | 0x20 | 32个字节 |
INFO | 温度相关参数 | 详见通信协议4.2 |
2.代码实现
- 获取温度保护参数: 保护参数存储在EEPROM,实现掉电不丢失
void Power_On_Read_Para(void)
{
uint8_t i;
//0-15 温度过高参数相关
//16-31 温度过低参数相关
//32- 47 电压过低参数相关
//48- 63 电压过低参数相关
//64 - 70 //校准参数相关
for(i = 0; i <= sizeof(threshold_params); i++)
{
Para_Buf[i] = AT24C02_ByteRead(SYSTEM_PARA_TEMP_ADDR + i);
}
}
- 指令处理逻辑
/***********************************************************************/
// 函数名称:SendTempParaData
// 函数描述:温度参数数据上传到上位机
// 输入参数:无
// 输出参数:无
// 其 他:无
/***********************************************************************/
void SendTempParaData(void)
{
uint8_t i = 0;
ShareBuf[0] = 0x7E; // 起始符
ShareBuf[1] = 0x46; // CID1
ShareBuf[2] = 0x02; // RNT
ShareBuf[3] = 0x20; // Len
for(i=0;i<32;i++)
{
ShareBuf[4+i] = Para_Buf[i];
}
ShareBuf[36] = CalculateCRC8(&ShareBuf[1], ShareBuf[3] + 3);; // CRC
ShareBuf[37] = 0xEF; // 结束符
Usart1_Transmitter(ShareBuf, ShareBuf[3] + 6); // 发送数据
}
三、指令扩展:读取其他参数
1. 读取ADC参数指令(CID2=03H,文档 4.3 节)
- 响应帧 INFO 字段:包含 12 字节参数(ADC1~ADC6),每参数占 2 字节,大端序。
2. 电压参数指令(CID2=04H,文档 4.4 节)
应用场景:配置电池管理系统(BMS)的过压 / 欠压保护阈值,参数掉电后通过 EEPROM 存储(后续章节详解)。
四、常见故障与排查指南
1. 响应帧异常类型
故障现象 | 可能原因 | 解决方法 |
---|---|---|
无响应 | 未收到请求帧 | 用示波器检查 TX/RX 波形 |
校验错误(F0H) | CHKSUM 计算错误 | 对比上位机与 STM32 校验逻辑 |
长度错误(F3H) | LENGTH 与 INFO 实际长度不一致 | 检查指令帧中 LENGTH 字段值 |
温度值异常 | 解析公式错误 | 确认单位换算系数(如 0.1℃) |
2. 实战排查案例
- 场景:上位机收到温度值为 - 255.0℃
- 排查步骤:
查看响应帧 INFO 字段为FF 00→原始值 0xFF00=-256(补码表示)
确认 STM32 发送的 INFO 应为00 F6,判断为发送时高低字节颠倒
修正代码:发送时先传高位0x00,再传低位0xF6
五、后续内容更新
- 下期预告 :
CSDN栏 模块一章节一《STM32 串口通信进阶:控制指令与数据存储实战》 - 互动福利 :
评论区留言 “协议”,赠送《本系列通信协议》PDF。
B站搜索相同ID:通信翻车员,可查看相关视频讲解
STM32 串口通信协议开发实战全攻略:STM32 串口通信・数据存储・Bootloader 全案例解析