485+MODBUS总结 第一章(完)
原创米亚拉斯 最后发布于2017-08-26 20:11:04 阅读数 8142 收藏
展开
RS485+MODBUS总结 第一章(完)
前言:
这一段时间又在瞎忙,感觉浪费了很多了时间。不过今天又恢复了干劲,把最近自己所学习的485做一次总结和分享。
先指定一下的计划:计划到年底,裸机主要学习和撰写485+MODBUS协议、CAN+CP/IP协议、USB+TYPEC协议,相关代码在M4做验证后发放执行代码;从新总结USART协议、SPI协议、IIC协议、单总线协议。当然,也要在IAR环境下用库函数编写并发放;学习蓝牙4.2协议的数据链路层+应用层通信、实现与微信数据透传等等,并在硬件上搭建出来,计划明年年初把文档做一次总结。
为什么要作总结呢?我感觉这些所谓的协议本就是双方所约定通用的通信格式,搞明白会用不就好了。但当我翻《MODBUS协议》官方手册的时候,好几百页,没看几页我都快睡着了。没办法,硬着头皮看了几十页,回头想想,之前看过的东西又全都想不起来了。所以对我来说,脑子容量有限,那就”把复杂的东西简单化,把简单的东西习惯化”不就好了。
好了,不啰嗦,开工!
物理层协议:交通路线,解决0和1数据链路传输问题。
一、为什么要采用485接口协议?(回答为本人的口述)
工业控制中常用到RS485接口,一是要求传输距离远;二是要求传输数据可靠;三是要求从机设备较多。而485的特点是:
1、数据传输可靠:采用电压差分结构;
2、为两线制:A和B,发送端发送时,Ua>Ub = 0; Ua\Ub =1;
接收端接收时,Ua>Ub =1; Ub>Ua =0;
所以厂家芯片需要内部集成收和发电路;
3、接口电平:双方统一即可,一般为 +(2\~6)V =1 、 -(2\~6)V=0;
4、传输距离远:一般最远为1K米左右;
5、传输速率高:由收发器的最高传输速率所决定,传输速率低则传输距离远。
6、支持节点多:由收发器所决定(通常由32、128、256、400MAX)
结合以上优点,所以使用485接口。
二、 为什么485必须要用MODBUS?
MODBUS为应用层协议。由于485通信只是单工通信(差分传输),故为了实现半双工通信(USART为半双工),所以需要主、从双方所约定的“通用法则”来进行半双工的数据通信。我的理解如果把485物理层比喻为数据传输的公路,则MODBUS就为交通规则。
当然,485不仅可以采用MODBUS协议传输,也可以采用TCP/IP 协议传输。
三、采用具体电路具体分析。
上图为光电隔离方式的 SP485R芯片的实际电路,该部分可直接被使用。
MCU的 UART串口的 RXD、 TXD 通过光电隔离电路连接SP485R 芯片的 RO、 DI引脚,控制信号 R/D 同样经光电隔离电路去控制 SP485R 芯片的 DE和/RE 引脚。
由微处理器输出的 R/D 信号通过光电隔离器件控制 485芯片的发送器或接收器使能:
① R/D 信号为“1”,则 485芯片的 DE 和/RE引脚为“1”,发送器有效,接收器禁止;此时,MCU可向485总线发送数据字节;
② R/D 信号为“0”,则 485芯片的 DE和/RE
引脚为“0”,发送器禁止,接收器有效;此时MCU可接收来自485总线的据字节。
注意:任一时刻,485芯片中的“接收器”和“发送器”只能够有 1个处于工作状态。(原因:是单工通信)。
器件作用:
①连接至 A 引脚的上拉电阻 R7、连接至 B 引脚的下拉电阻 R8 用于保证无连接的485芯片处于空闲状态,提供网络失效保护,以提高 485节点与网络的可靠性。
②使用 DC-DC 器件可以产生 1 组与微处理器电路完全隔离的电源输出, 用于向 RS-485收发器电路提供+5V 电源。
③电路中光耦器件的速率将会影响 RS-485 电路的通讯速率。
上图中选用了 NEC公司的光耦器件 PS2501 芯片,受 PS2501 芯片的响应速率影响,这一示范 RS-485接口电路的通讯速率只可保障在 19200bps 速率以下正常工作;如果需要达到更高的RS-485 通讯速率,则需要选用响应速度更快的光耦器件,比如 Agilent公司的超高速光耦元件。
好了,硬件协议就总结到这里,接下来总结MODBUS协议!
MODBUS协议:交通规则,让主、从双方更可靠的半双工通信。
一、你说把MODBUS比喻为“交规”,那规则是啥?(MODBUS协议下讲述)
我的理解MODBUS和IIC倒是有相似之处(可以自己体会一下),可以比喻为在队列中,队长(主机)点名,点到名字的队员(从机)应答(包括“到!”和“回答的其他信息==数据”)。简单总结,可以分为以下几点:
①. 系统中,只允许有一个设备为主机;
②. 任何时候,从机不允许向主机发送数据;
③ 系统上电后,主机与所有从机都要默认保持为接收状态(监听状态);
④ 每次的数据交换都要由主机发起:
具体实现过程为:
a.首先主机将自己转为发送状态;
b.主机按预先约定的格式主机发出寻址帧→主机恢复为接收态;
c.等待所寻址的从机做应答;
二、那说了这么多,你总要让我们知道MODBUS适用于哪里吧?
MOSBUS适用于”一主多从”的结构,如下图:
为什么这么定义的呢,这是由于像上图所示的电路结构所决定的:所有设备的通讯总线连在一起,这样协议就不具备冲突检测;举个例子,也就是主机给从机1发送数据后,从机要做回应,此时回应的数据加载到数据总线上,那么所有的从机都能”看得见”,那么问题来了,跟谁聊天呢!
所以MODBUS定义:
①只能由一台主机;
②每个从机都必须有一个唯一的地址。
③那么你那地址是啥?怎么定义?
其实呢,你可以理解每个从机的地址为手机号,但这样比喻的并不恰当,为什么这么说呢。那是因为咱么最终代码的实现还是要通过C语言来写出来,而发送的数据包中都含地址域,说的明确一点,那就是所有从机都判断定义好的从机ID(寻址),而不是像手机一样,拨打谁的号码就只有给他打电话。
三、那MODBUS对地址有什么要求,不会是无穷多个随便定义吧?
当然不是。协议规定,MODBUS地址范围为0\~247,其中0号地址为 广播地址(主机呼叫所有用户),即主机向0号地址发送数据,也就是把该数据包发送至所用从机(群聊!
四、你上边说主机发送后从机必须要回答,这么多用户不会都一一回答吧?
不是的,为了避免冲突,所以协议规定:主机向地址0(所有从机)发送的时候,所有的从机都不做回应(默默地抢红包就好)。
五、好了,正经的来了! MODBUS的主机寻址帧格式(数据结构)
首先了解MODBUS的两种编码格式:RTU格式 和 ASC格式;
首先来大概了解一下RTU格式和ASC格式:
RTU:远程终端控制单元。可以称他为 ”十六进制编码”或叫”二进制”也可以。
假如说我数据要发送0X03,那么这里发送格式如下:
很明显,我要将0X03以二进制码0000 0011发送。其RTU格式为1+8+1=10位!
ASC:是不是感觉很眼熟,没错,这就是ASCII的简写!还是以0X03为例:
也就是把数据都以ASC码方式转换为二进制发送,这样传输就多了8个字节, ASC格式为1+8+8+1=18位!
六、采用了RTU格式,为嘛还要采用ASC格式呢,多了8位…?
首先说下RTU编码格式的优点:效率高!当然,ASC效率就低了,但是这样做有一个好处,就是咱的PC机只是别ASCII码的32-126,要是不在这个范围之内肯定就为一堆乱码了!
所以采用ASC的好处就是,可以通过监控设备在总线上读取数据在PC机上打印出来,这样方便调试。
建议在工作中采用RTU格式,而学习/调试可采用ASC编码格式。当然,这两种编码方式之间也可以相互转换!
七、正经的又来了! RTU编码格式
从机地址就不用多说了;功能码就是指”做什么”的问题;
而这里要加校验位为了提高数据的可靠性,RTU采用CRC16的校验方式;其数据包末尾加16位的校验位,当然校验位是采用他特定格式的算法得出的。
很明显,数据包末尾没有所谓的停止位,从机是怎么区分这个数据结束了的呢?
协议规定:主机发送的数据包的停顿时间到达3.5个字符时间作为结束的”标志”,从机就认为此次数据结束。假如说此次<3.5字符时间,则从机会认为继续接收!
* 那么,这3.5个字符时间到底为多长时间呢?
我们举个例子:假若我们串口波特率是9600bit/s(每秒发送9600位),则每位发送的时间t=1000000us/9600≈104us;
而一个字需要10位(上文有解释),则一个字节所耗费的时间为:T=10X104us=1040us;
则3.5T=3.5X1040us=3645us≈4ms;这里我们选取4ms!
这个时间只是一个参考时间,不用太精确,我们也可以选取5-6ms;
也就是说咱们程序中,需要做两个准备:
①硬件定时器,32可以定时为1ms,51可以定义为2ms,都没关系;
②串口;
RTU代码较为复杂!到此,RTC编码格式介绍完毕。
八、ASC编码格式
与RTU除了上述不同,ASC编码方式是有”开始位”和”停止位”:
开始位:’:’,ASCII码为0X3A;
停止位:’/r/n’,ASCII码为13、10;
校验码:采用LRC校验,他怎么计算呢?
计算方法:
①LRC=(地址码)+(功能码)+(数据1)+(数据2)+ … +(数据N);
②LRC/256后取余数,其结果不会超过256,所以它的范围为0\~255;
③再将计算结果取反+1(补码);
就这么简单哈,计算量明显比RTU格式简单许多,但是数据量增大了。
九、从设备的数据包的应答格式
从设备回答要与主机查询的数据包格式要一致,主机用RTU,那么我也用这种格式!
我们想啊,从机回包也就两种可能:
①你要的我能正确的给你;
②你要的我没有或者数据不对;
所以也有数据传输的功能码也有
能正确回应时,功能码与主机发送的功能码保持一致!
不能正确回应时,从机回应的功能码要在接收到主机的功能码的基础上+128;
那么主机收到从机功能码后判断是否<128,是的话则从机传输的数据是可靠的;反之,是不可靠的。主机可将正确性显示到LCD等直观设备上…做出提示!
非常重要:*MODBUS正常的功能码一定<128*!
第一章 完
本章结束语:
哎呀,终于写完了,感觉写着挺费劲的,本来我这个就学了1个小时,但是写这个总结却花了我整整六个小时。但是写下来确实是有收获的,最起码是记得更牢靠了。
接下来第二章会总结485+MODBUS具体代码的实现,具体操作就是用PC机充当主机,然后自己写一个程序下载到M4开发板中(充当从机)—–485发送/接收—–PC机通信。
如果有错误的地方,请批评指正,谢谢!
————————————————
版权声明:本文为CSDN博主「米亚拉斯」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013048421/article/details/77606549