OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3020|回复: 7

STM32如何通过串口发送长数据帧

[复制链接]

1

主题

6

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2018-12-19
在线时间
3 小时
发表于 2020-5-21 21:22:47 | 显示全部楼层 |阅读模式
5金钱
在做毕业设计。在调试通讯部分需要STM32通过串口发送modbus协议的数据,数据挺长的,而且要发送16进制数据,类似这样:01460000000204 00120025 712F,此帧数据中前14边是操作指令和操作寄存器,中间八位是传感器测得的数据位,最后四位是CRC校验,CRC部分是需要计算的,请问我如何编写C程序控制单片机让串口一下子打印这么长的数据,而且还要引用变量。查了点资料,对照着串口通讯的例程和printf操作语法规则尝试了几十次没能出结果,有点转不过这个弯了,特向各位大佬求助,希望尽快得到回复。

最佳答案

查看完整内容[请看2#楼]

很简单啊。你只是对modbus协议不是很清楚。按你的意思,你应该使用读功能码(0x03):帧格式如下: 主节点发送帧格式: 序号 0 1 2 3 4 5 6 7 字段定义 ADDR CMD MSB LSB MSB LSB LSB MSB 解释 控制器地址 命令类型 寄存器起始地址 寄存器个数 CRC校验 从节点正常应答帧格式: 序号 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
发表于 2020-5-21 21:22:48 | 显示全部楼层
很简单啊。你只是对modbus协议不是很清楚。按你的意思,你应该使用读功能码(0x03):帧格式如下:
主节点发送帧格式:
序号                0                           1                  2                  3                   4            5                  6          7
字段定义           ADDR                        CMD        MSB          LSB                MSB          LSB        LSB        MSB
解释                控制器地址              命令类型        寄存器起始地址        寄存器个数        CRC校验

从节点正常应答帧格式:
序号                     0                   1                         2                              3     4                              5     6                      ...            L+1 L+2                 L+3        L+4
字段定义        ADDR          CMD            Length                           MSB LSB                   MSB LSB                           MSB LSB                 LSB        MSB
解释            控制器地址        命令类型        发送字节数L=n*2        第一个寄存器值        第二个寄存器值        ...        最后一个寄存器值        CRC校验

CRC校验算法:
u16 count_CRC(u8 *addr,u32 num)
{
        u16 crc = 0XFFFF;
        u32 i;
        while(num --)
        {
                crc ^= *addr++;
                for(i = 0;i < 8;i++)
                {
                        crc = (crc & 0x0001) ? ((crc>>1)^0xA001)crc>>1);
                }
        }
        return crc;
}

读03功能码需要你自己去写哦,还有异常码的回复需要自己去写。另外,可以通过DMA+空闲,这样就更快了
回复

使用道具 举报

0

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2018-12-27
在线时间
0 小时
发表于 2020-5-21 21:22:50 | 显示全部楼层
帮顶,大家来帮忙解答一下。。
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2018-12-19
在线时间
3 小时
 楼主| 发表于 2020-5-22 11:05:17 | 显示全部楼层
顶,求各位帮下忙
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2018-12-19
在线时间
3 小时
 楼主| 发表于 2020-5-22 15:46:42 | 显示全部楼层
谢谢你,问题已经解决了大部分,当前还有个问题需要向你请教,串口打印的数据问题。
u16 a=0x0146;
printf("%04X",a);
串口打印的结果是0146,但是协议中的数据格式为16进制格式,串口默认为十进制显示。当我打开串口助手点击十六进制显示,
其显示为30 31 34 36,但是我使用控制符确实是让其16进制输出,请问我如何正确的让其在在串口输出十六进制显示的正确数据?
多谢回复,不胜感激。
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2018-12-19
在线时间
3 小时
 楼主| 发表于 2020-5-22 15:48:18 | 显示全部楼层
自己给自己顶一下,希望能得到有懂这个小问题的大佬的帮助,不胜感激。
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2018-12-19
在线时间
3 小时
 楼主| 发表于 2020-5-22 15:50:36 | 显示全部楼层
jiangyy 发表于 2020-5-22 11:41
很简单啊。你只是对modbus协议不是很清楚。按你的意思,你应该使用读功能码(0x03):帧格式如下:
主节点 ...

不好意思忘记点击单独回复,谢谢你的帮助,我直接盖了一层楼又提出了一个小问题,希望能得到你的解答。
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2018-12-19
在线时间
3 小时
 楼主| 发表于 2020-5-22 23:56:08 | 显示全部楼层
已经搞懂,单片机需要向串口发送字符型数据,类似于通过串口助手发送的文本数据,而不是我想当然理解的整形数据,当前已经将通讯调试完成,再次感谢这位朋友。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-1 18:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表