• [FreeModbus源码分析] 1.协议简介


    MODBUS协议分为两层,一层是数据链路层,一层是应用层。在官网上,分别有两篇文档描述了MODBUS的数据链路层和应用层。当然,数据链路层有多种实现方式,官网给的是基于串行的方式。两篇文档分别为 MODBUS over Serial Line Specification and Implementation Guide 和 MODBUS Application Protocol Specification。两篇specifiaction 加起来100页左右,很快就能看完。所以那些想学协议的同学,最好是从官网下载正规的规格书。

    FreeModbus协议是一个基于MODBUS协议的开源实现,实现了从机部分的功能。代码不长,移植也十分方便。

    数据链路层


    在此层上,MODBUS是主从结构,一个总线上只能有一个主机,允许有247个从机,所有的通信都是由主机发起的。主机有两种发送模式,一种是单向,另一种是广播。MODBUS的地址空间一共有256个,第0个用于广播,248-255保留,剩余247个分配给从机,而主机是没有地址的。


    MODBUS的数据单元(protocol data unit, PDU)由功能码和数据组成,而在物理层上的一帧则是在PDU前加上地址,在PDU后加上CRC校验组成。



    有两种串行传输模式。一种是RTU(remote terminal unit),另一种是ASCII。RTU应用的更多一些,在 specification 中,明确规定,RTU是必须实现的,而ASCII只是可选的。
    RTU的优势在于信息比ASCII更紧凑,也就是传输的更快。RTU中每一个字节是11 bits,由1个起始位,8个数据位,1个奇偶校验位,一个停止位。默认是偶校验位。



    在MODBUS中,是用时间间隔来区分每一帧的,由此可以联想到,单片机实现的时候一定要用定时器。每一帧的间隔要大于3.5倍的字符,每两个字节之间不能大于1.5个字符,否则会认为出错。
    在波特率小于19200的时候,这两个规则必须实现。当大于19200的时候,t3.5取为1750us,t1.5取为750us。

    在每一帧的最后是CRC16校验。校验的c实现,在 specification 上已经给出。起始位,校验位,结束位不参与CRC校验。

    从机的状态转换图如下


    这可以用状态机实现。


    应用层


    应用层是一种请求和响应的模式,功能是由功能码指出。值得一提的是MODBUS还可以通过TCP/IP协议的502端口来实现通信。

    PLC中数据分为四种,线圈,数字量输入,输入寄存器和保持寄存器。前两种是可以位访问,后两种是字访问。对于每一种数据,其数据可以分别寻址,从0-65535。


    特别指出,这里地址是以MODBUS而言的。与设备中的寄存器地址有别。
    寄存器信息地址(PLC地址)
    寄存器信息地址指的是存放于控制器中的地址,这些控制器可以使PLC,也可以是触摸屏,或是文本显示器。例如40001,30002等,这些地址一般使用10进制描述。
    寄存器寻址地址(协议地址)
    寄存器寻址地址指的是通信时使用的寄存器地址,例如信息地址40001对应寻址地址0x0000,40002对应寻址地址0x0001,寄存器寻址地址一般使用16进制描述。再如,信息寄存器40003对应寻址地址0002,信息寄存器30003对应寻址地址0002,虽然两个信息寄存器通信时使用相同的地址,但是需要使用不同的命令才可以访问,所以访问时不存在冲突。


    功能码


    一共有127个功能码,其中部分是公用的,其他可以用户自己定义。



    现在举一例
    功能1 读寄存器值
    这个功能可以读1-2000个连续的寄存器值。读时需要制定起始寄存器地址,寄存器数量。如果请求的格式正确,则返回寄存器数量,和每一位寄存器值,对于不是8的倍数的寄存器数量请求,则添0补全。
  • 相关阅读:
    Windows Driver Mode 1
    一个程序员的奋斗经历 2
    JavaScript判断文件是否存在
    流程图个图标详解
    wget for windows
    软件的开发周期
    Firefox支持activex的插件
    第二次作业
    C/C++字符串使用整理
    c#学习小记录(1)
  • 原文地址:https://www.cnblogs.com/lyyyuna/p/4123925.html
Copyright © 2020-2023  润新知