前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >以太网通信控制板-关于MODBUS, IEEE754浮点数, 字节和位的转换

以太网通信控制板-关于MODBUS, IEEE754浮点数, 字节和位的转换

作者头像
杨奉武
发布2023-05-23 14:42:10
4170
发布2023-05-23 14:42:10
举报
文章被收录于专栏:知识分享知识分享知识分享

MODBUS协议

1,协议 == 格式

01 05 00 00 FF 00 8C 3A  这是MODBUS发送控制继电器吸合的一条数据

01 代表地址,这是为了区分多个设备

05 代表功能码,代表后面数据的功能,MODBUS规定05是写线圈命令

00 00 代表控制哪一路线圈,也就代表线圈的地址

FF 00 代表控制线圈吸合,这是规定

8C 3A 是前面的数据计算CRC16之后得到的16位数据,然后低位在前,高位在后

然后看这句话: 上面的看看就行啦,后面的才是要知道的.

2,假设我现在要发送个数据控制设备的继电器

假设设备地址是 0x01;  继电器地址是0x00 0x00;  控制继电器吸合

为了便于观察数据,每隔3S通过调试口输出数据

其实呢最主要的是计算CRC,还有就是注意下CRC的高低位, 有些设备规定把高位放到前面有些规定把低位放到前面.

modbus-16/modbus  计算方式是不变的,  如果设备是使用modbus-16/IBM 就把下面的值改为0

3,假设我现在要接收个MODBUS数据控制继电器

我就用板子的调试口来测试接收数据

01 05 00 00 FF 00 8C 3A   //控制吸合

01 05 00 00 00 00 CD CA  //控制断开

4,返回执行状态

5,补充知识,假设有个设置多路线圈(这块板子其实用不到,毕竟功能上主要作为DTU透传)

假设过来的数据是  0x55, 代表了设置8路线圈;

0x55对应二进制   01010101  咱就规定从左到右分别是代表控制第1路到第8路继电器, 0代表断开,1代表吸合

那边上面就是控制第1,3,5,7路断开; 控制第2,4,6,8路吸合;

然后就是用的字节和位之间的转换,

参考使用

反过来,是把位转为byte

IEEE754规约

1,假设我要发送个数: 678384324 ,假设用四字节来表示

平常的做法是不是  >>8啦  >>16啦  >>24啦 然后赋值

看下面的做法

只是注意一点,这个单片机转换以后,数据的低位存储在了数组的低位, 数据的高位存储在了数组的高位

(低位)0xc4,0x52,0x6f,0x28(高位)

所以真实的是  0x286f52c4

2.反过来转换就是

3,再看浮点数

反过来

4.注意哈这是标准的做法,而且高级语言C#,C++,JS,PHP啥的也是这样子的转换标准

列如C#

65536 转为16进制

   byte[] byt = BitConverter.GetBytes(65536);//转为byt,默认就是转成4字节

  转换之后  

  byt[0] = 0x00;

  byt[1] = 0x00;

  byt[2] = 0x01;

  byt[3] = 0x00;

220.5 转为16进制

//和咱单片机定义联合体解析一样的道理 //转为byt,默认就是转成4字节 byte[] byt = BitConverter.GetBytes(220.5f);

转换之后:

byt[0] = 0x00; byt[1] = 0x80; byt[2] = 0x5c; byt[3] = 0x43;

注意:220.5f  后面需要加f

否则会按照double数据类型进行转换

按照 double 进行转换的,转换出来是8字节

byt[0] = 0x00;

byt[1] = 0x00;

byt[2] = 0x00;

byt[3] = 0x00;

byt[4] = 0x00; byt[5] = 0x90; byt[6] = 0x6B; byt[7] = 0x40;

有16进制整形数据了,转为整形数据

  假设数据是65536    : 00 01 00 00

  byte[] byteValue = new byte[4];

  byteValue[3] = 0x00;   byteValue[2] = 0x01;   byteValue[1] = 0x00;   byteValue[0] = 0x00;

  int intValue = BitConverter.ToInt32(byteValue,0);

  intValue 就是 65536

有16进制浮点数数据了,转为浮点数

  假设数据是 220.5     :43 5C 80 00

  byte[] byteValue = new byte[4];

  byteValue[0] = 0x43;   byteValue[1] = 0x5c;   byteValue[2] = 0x80;   byteValue[3] = 0x00;

  float floatValue = BitConverter.ToSingle(byteValue, 0);

  floatValue计算出来就是 220.5

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1,协议 == 格式
    • 01 05 00 00 FF 00 8C 3A  这是MODBUS发送控制继电器吸合的一条数据
      • 01 代表地址,这是为了区分多个设备
        • 05 代表功能码,代表后面数据的功能,MODBUS规定05是写线圈命令
          • 00 00 代表控制哪一路线圈,也就代表线圈的地址
            • FF 00 代表控制线圈吸合,这是规定
              • 8C 3A 是前面的数据计算CRC16之后得到的16位数据,然后低位在前,高位在后
                • 然后看这句话: 上面的看看就行啦,后面的才是要知道的.
                • 2,假设我现在要发送个数据控制设备的继电器
                  • 假设设备地址是 0x01;  继电器地址是0x00 0x00;  控制继电器吸合
                    • 为了便于观察数据,每隔3S通过调试口输出数据
                      • 其实呢最主要的是计算CRC,还有就是注意下CRC的高低位, 有些设备规定把高位放到前面有些规定把低位放到前面.
                        • modbus-16/modbus  计算方式是不变的,  如果设备是使用modbus-16/IBM 就把下面的值改为0
                        • 3,假设我现在要接收个MODBUS数据控制继电器
                          • 我就用板子的调试口来测试接收数据
                            • 01 05 00 00 FF 00 8C 3A   //控制吸合
                              • 01 05 00 00 00 00 CD CA  //控制断开
                              • 4,返回执行状态
                              • 5,补充知识,假设有个设置多路线圈(这块板子其实用不到,毕竟功能上主要作为DTU透传)
                                • 假设过来的数据是  0x55, 代表了设置8路线圈;
                                  • 0x55对应二进制   01010101  咱就规定从左到右分别是代表控制第1路到第8路继电器, 0代表断开,1代表吸合
                                    • 那边上面就是控制第1,3,5,7路断开; 控制第2,4,6,8路吸合;
                                      • 然后就是用的字节和位之间的转换,
                                        • 参考使用
                                          • 反过来,是把位转为byte
                                          • IEEE754规约
                                            • 1,假设我要发送个数: 678384324 ,假设用四字节来表示
                                              • 平常的做法是不是  >>8啦  >>16啦  >>24啦 然后赋值
                                              • 看下面的做法
                                              • 只是注意一点,这个单片机转换以后,数据的低位存储在了数组的低位, 数据的高位存储在了数组的高位
                                              • (低位)0xc4,0x52,0x6f,0x28(高位)
                                              • 所以真实的是  0x286f52c4
                                            • 2.反过来转换就是
                                              • 3,再看浮点数
                                                • 反过来
                                              • 4.注意哈这是标准的做法,而且高级语言C#,C++,JS,PHP啥的也是这样子的转换标准
                                                • 列如C#
                                                • 65536 转为16进制
                                                • 220.5 转为16进制
                                                • 有16进制整形数据了,转为整形数据
                                                • 有16进制浮点数数据了,转为浮点数
                                            领券
                                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档