当前位置: 代码迷 >> 综合 >> 光照度传感器之RS485 通信与 Modbus 协议
  详细解决方案

光照度传感器之RS485 通信与 Modbus 协议

热度:2   发布时间:2023-12-13 02:16:19.0

早先学51时,宋老师的书上就有Modbus这方面的知识,可是当时实验环境不足也没去深究,现在做项目用到了RS485这类传感器和Modbus协议,特地来记录下。


一、传感器介绍

使用的传感器是一款光照度传感器,如下图所示。

Alt

该传感器一共有五根线,颜色与功能有下表所示对应关系。

颜色 功能
棕色线 电源正(12-24V)
黑色线 电源负(12-24V)
黄色线 485-A
蓝色线 485-B

注意,485的A和B千万不要接反了!

设备默认地址为0x01

该传感器的只能通过0x03指令读取光照度信息,光照度数据一共32位,高16位在地址为0x07的寄存器中,低16位在地址为0x08的寄存器中。

二、RS485介绍

1、RS485特点
  • 数据信号采用差分传输方式,可以有效的解决共模干扰问题
    • 逻辑“1”以两线之间的电压差为+(0.2~6)V 表示,逻辑“0”以两线间的电压差为-(0.2~6)V 来表示,是一种典型的差分通信
  • 最大距离可达 1200 米
  • 最大传输速度可以达到 10Mb/s 以上
    • 它的传输速率和传输距离是成反比的,只有在 100Kb/s 以下的传输速度,才能达到最大的通信距离,如果需要传输更远距离可以使用中继。
  • 允许多个收发设备接到同一条总线上
    • 可以在总线上进行联网实现多机通信,总线上允许挂多个收发器,从现有的 RS485芯片来看,有可以挂 32、 64、 128、 256 等不同个设备的驱动器
  • RS485 的接口非常简单, 与 RS232 所使用的 MAX232 是类似的,只需要一个 RS485转换器,就可以直接与单片机的 UART 串口连接起来,并且使用完全相同的异步串行通信协议。
    • 但是由于 RS485 是差分通信,因此接收数据和发送数据是不能同时进行的,也就是说它是一种半双工通信。(所以后面有了控制输入和输出方向的dir位!)
2、RS485典型硬件电路

在这里插入图片描述

其中,485-RX和485-TX可直接与单片机的串口相连。485-DIR接至普通输出IO口即可,用来控制通信方向:默认一直低电平(处于接收状态),当发送时将其拉高,发送完毕再拉低!

三、Modbus通信协议介绍

1、Modbus介绍

UART、 I2C、 SPI 这些通信协议,都是最底层的协议,是“位”级别的协议。Modbus这种通信协议是字节级别的,叫做应用层通信协议。该协议描述了控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误记录,它制定了通信数据的格局和内容的公共格式。

在进行多机通信的时候, Modbus 协议规定每个控制器必须要知道它们的设备地址,识别按照地址发送过来的数据,决定是否要产生动作,产生何种动作,如果要回应,控制器将生成的反馈信息用 Modbus 协议发出。

2、RTU 协议帧数据

Modbus 有两种通信传输方式,一种是 ASCII 模式,一种是 RTU 模式。在实际场合中使用的比较多的当数RTU协议帧模式了。一帧RTU格式如下图所示:

在这里插入图片描述
Modbus 的 RTU模式规定不同数据帧之间的间隔是 3.5个字节通信时间以上(通常设置为5ms)。

设备地址:每个设备都有一个自己的地址,当设备接收到一帧数据后,程序首先对设备地址字节进行判断比较,如果与自己的地址不同,则对这帧数据直接不予理会,如果与自己的地址相同,就要对这帧数据进行解析。

如果地址是 0x00,则认为是一个广播命令,就是所有的从机设备都要执行的指令。

功能代码:在第二个字节功能代码字节中, Modbus 规定了部分功能代码。我们常用的是0x03:读取一个或连续的寄存器以及0x06:写入单个寄存器。该项目中使用的光照度传感器,我们主要是在程序中读取该传感器的数据,因此本文着重介绍0x03功能码。

数据:跟在功能代码后边的是 n 个 8bit 的数据。这个 n 值的到底是多少,是功能代码来确定的,不同的功能代码后边跟的数据数量不同。当主机向从机(传感器)发送读取数据的请求命令时,主机发送的数据 n 的组成部分就是: 2 个字节的寄存器起始地址,加 2 个字节的寄存器数量 N。如下图所示:
在这里插入图片描述
当从机接收到主机的请求命令,回应主机发送的命令时,从机数据 n 的组成部分是: 1 个字节的字节数,因为我们回复的寄存器的值是 2 个字节,所以这个字节数也就是 2N 个,再加上 2N 个寄存器的值。如下图所示:
在这里插入图片描述

可能这里还会有点绕,不过没关系。到后面结合我们实际的传感器数据,再来看这些规定也许就会一切明朗了。对了,需要提到的一个事情是:在 Modbus 协议里寄存器的地址和数值都是 16 位的(两个字节)。

CRC校验:CRC 校验函数把一帧数据除最后两个字节外,前边所有的字节进行特定的算法计算,计算完后生成了一个 16bit的数据,作为 CRC 校验码,添加在一帧数据的最后。接收方接收到数据后,同样会把前边的字节进行 CRC 计算,计算完了再和发过来的 16bit 的 CRC 数据进行比较,如果相同则认为数据正常,没有出错,如果比较不相同,则说明数据在传输中发生了错误,这帧数据将被丢弃,就像没收到一样,而发送方会在得不到回应后做相应的处理错误处理。

关于具体的CRC校验算法,如果实在看不懂,也可不必深究,先会用!

四、传感器通信实例

下面将使用两个Modbus调试上位机,演示实际的Modbs通信过程。两款上位机均可从<这里>获取。提取码:fkc9

1、通用的Modbus调试精灵

界面如下图所示:

在这里插入图片描述

通过RS485转串口设备,将传感器接到电脑选择对应的COM口,其他设置如上图所示,然后点击打开串口。在读寄存器区写入寄存器地址为:7,数量为2。(即读取0x07和0x08两个寄存器的内容)在发送窗口写入01 03 00 07 00 02 75 CA,点击读出,便会接收到01 03 04 00 00 00 00 5F BA 0B

下面将分别详细解释发送和接收的每个字节含义。

发送

内容 含义
01 设备地址
03 功能码
00 要读取的起始地址高位
07 要读取的起始地址低位
00 寄存器数量高位
02 寄存器数量低位
75 CRC校验高位
CA CRC校验低位

接收

内容 含义
01 设备地址
03 功能码
04 读取的字节数
00 0x07地址的高8位
00 0x07地址的低8位
00 0x08地址的高8位
5F 0x08地址的低8位
BA CRC校验高位
0B CRC校验低位

所以我们读取到的光照强度位:0x42,即95Lux

这里再次体会前面的协议规定中的主机发送请求,从机发送回应。还有前面提到的在 Modbus 协议里寄存器的地址和数值都是 16 位的(两个字节)。

2、专用的光照强度Modbus调试上位机

这个当然就是和这个传感器配套的上位机咯~

在这里插入图片描述
但是协议和上面介绍的通用一毛一样,可以比对学习。


emmmm,整个协议的分析和数据的读取到这里基本告一段落。

  相关解决方案