栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C#做Modbus TCP通讯对接C++注意

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#做Modbus TCP通讯对接C++注意

1.浮点数类型数值与C++的Dword类型

最近对接一份协议使用Modbus TCP,下位机跟硬件的同事给过来的对接协议上对值类型的描述是word跟Dword。一开始并没有想那么多,按照C#惯用的UShort通过BitConverter.GetBytes()转成byte[]根据协议套到指定位置就好,做好给到下位机去测试才发现的问题:在涉及到协议中的Dword类型的值时,给出去或者读取到的值都会有问题。

按照同事的说法,他们要的是32位的有符号浮点类型数值。

所以,在C#代码中我们使用float即可:

            BitConverter.GetBytes((ushort)1);
            float f = -33.23f;
            byte[] byteDatas = BitConverter.GetBytes(f);
            //Array.Reverse(byteDatas);
            string dataStr = BitConverter.ToString(byteDatas);//85-EB-04-C2

转出来的byteDatas的count是4位,至此我才想明白协议内容上偶尔会空出一个地址的原因,同样,模拟器上值设定成float后也会空出一位,作为上一位数值字长的补充:,这种情况下就得使用写多个寄存器的方式0x10来写值了。

 同时,我们还需要留心下位机这里的方式:

也可能是float inverse类型等,需要根据实际情况调整转换的值。

2.同时读多个线圈

一开始我并没有意识到0x01功能号中数据长度的意义,事实上,数据长度如果超过当前地址的值,会往后延伸到后面的地址。寄存器也同理,如上述的一个值占用两个地址等。

在Modbus中,一个地址占2个字节,超过,当然就算下个地址了。

而在报文里面,一般1个地址也是由2个字节进行描述。

我们可以设定好地址和数据长度, 对返回的数据做处理:

            string resultStr = "";
            byte[] resultBytes = new byte[] { 0xCA, 0xE0, 0x00, 0x09 };
            foreach (byte item in resultBytes)
            {
                string temp = Convert.ToString(item, 2).PadLeft(8, '0');
                char[] resultChars = temp.ToCharArray();
                Array.Reverse(resultChars);
                resultStr += new string(resultChars) + " ";
            }
            //01010011 00000111 00000000 10010000 

如下,可以对应上线圈的状态:

 

关于Modbus TCP更加基础的学习,可以参照:ModbusTCP协议学习笔记_iknow_nothing的博客-CSDN博客_modbustcp

同时,可以借助网络调试工具,对照学习:NetAssist网络调试助手 V5.0.2-软件工具-野人家园 (cmsoft.cn)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/717840.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号