当使用485通讯口获取DDSU666导轨式电能表数据时,发现会出现电表不回复数据。
- 原因分析
1包数据串口会当成多包发送。
由于大傻调试工具显示时间只能到秒,更换串口调试软件后
当一包数据被当成多包发送时,如果间隔时间超过5ms,则电表不回复数据,如果等于5ms则回复数据。
根据DTSU666说明书,帧间隔需要大于3.5个字符的停顿间隔
计算停顿间隔
1、Modbus 协议报文间隔需要大于3.5个字符计算:
1.1、有检验位
1个字符=1(起始位)+8(数据位)+1(奇偶校验位)+1(停止位)=11位
3.5个字符=3.5*11=38.5位
如果波特率=9600bps,则3.5个字符间隔时间为38.5/9.6=4.0104167毫秒
1.2、无校验位
1个字符=1(起始位)+8(数据位)+0(无校验位)+1(停止位)=10位
3.5个字符=3.5*10=35位
如果波特率=9600bps,则3.5个字符间隔时间为35/9.6=3.6458毫秒
2、通常可以将传输45位的时间四舍五入后做为报文时间间隔。
如果波特率=9600bps,则45位传输时间为45/9.6=4.6875≈5毫秒
- 问题解决与改进
原因我们已经知道了,1包数据,串口会当成多包数据发送。
查看串口配置:
当串口打开是,对输出做了如下配置:
new_settings.c_oflag &= ~ONLCR;
new_settings.c_oflag &= ~OCRNL;
观察得知串口配置没有禁用输出处理
修改代码如下:
new_settings.c_oflag &= ~ONLCR;
new_settings.c_oflag &= ~OCRNL;
//禁用输出处理
new_settings.c_oflag &= ~OPOST;
测试结果如下:
测试每次发送数据都能获取到电表回复,问题解决。
参考连接:
Linux 串口编程 - 走看看
Linux C 串口属性设置_御龙冀人的博客-CSDN博客
struct termios_Jerry_Lee01的博客-CSDN博客
linux termios 详解_Nightsong_cc的博客-CSDN博客_linux tcdrain
Linux下串口编程入门 - 冷烟花 - 博客园
Modbus协议 报文间隔3.5个字符_Owen_SYC的博客-CSDN博客_modbus字节间隔