Modbus通信协议的FPGA实现
扫描二维码
随时随地手机看文章
现场总线是一种应用于生产现场,在现场设备之间,现场设备与控制装置之间实现双向、串行、多节点数字通信的技术。Modbus协议其节点安装数量非常多,安装的地区遍及世界各地。
今天的FPGA可包含内嵌乘法器、专用计算例程和片上RAM等,加上FPGA的并行性,其结果比最快的DSP芯片还要快上500倍乃至更多。随着FPGA价格不断下降,甚至最小的器件都足以实现一个集成可选定制I/O功能的软处理器核。可见,FPGA对嵌入控制应用越来越具有吸引力。
目前Modbus协议实现方式多为单片机和PLC,随着FPGA的广泛应用,研究Modbus现场总线的FPGA解决方案有很大的实用价值。
1 Modbus协议简介
Modbus串行链路系统可以使用不同的物理接口(RS 485,RS 232),最常用的是RS 485两线制接口。为了提高通信模块在工业应用中的抗干扰性和稳定性,接口芯片和FPGA核心模块之间应加入高速光耦进行隔离,总线两端处放置线路终端电阻,采用屏蔽双绞线作为通信线等。
在串行链路上,Modbus RTU(Remote Terminal Unit)模式报文中每8个位字节含有两个4位十六进制字符,这种模式的主要优点是较高的数据密度,在相同的波特率下比ASCII模式有更高的吞吐率。RTU模式每个字节(11位)的格式如图1所示,支持奇、偶和无校验,使用无校验时要求2个停止位。Modbus RTU帧最大为256B,由发送设备将Modbus报文构造为带有已知起始和结束标记的帧,报文帧由时长至少为3.5个字符时间的空闲间隔区分,整个报文帧必须以连续的字符流发送,如果两个字符之间的空闲间隔大于1.5个字符时间,则报文帧被认为不完整被接收节点丢弃,如图1所示。
在应用层上,Modbus是一个请求/应答协议,并且提供功能码规定的服务。有三类Modbus功能码:公共码、用户定义码和保留码,大多数情况下只用公共码,其主要包括比特(线圈)访问、16 b(寄存器)访问、文件记录访问、诊断和其他信息访问。
2 Modbus RTU通信协议接口设计
2.1 接口功能及模块划分
Modbus RTU接口框图及输入、输出引脚示意图如图2所示。
在某一确定的主时钟频率、通信波特率和奇偶校验方式下,通过设置CE_Modbus和R_Tn的状态,可以控制该接口模块处于接收Modbus协议帧模式、发送Modbus协议帧模式或输入/输出寄存器操作模式,如表1所示。
典型的波特率和奇偶校验位设置如表2、表3所示。这两组控制信号可以从端口引出接到拨码开关,然后可以通过调节拨码开关来灵活控制该设备奇偶性与波特率,也可以通过寄存器配置方式控制。
2.2 接收过程
(1)系统处于接收Modbus协议帧模式下之后,清零标志位和定时器,然后启动定时器,如果检测到有串口输入数据,则清零定时器,如果没有检测到串口输入数据且定时器第一次计时到3.5个字符时间,置帧起始标志;
(2)把接收到的第一个字符放入接收缓冲寄存器的0x00地址(协议帧最长为256 B,故接收缓冲大小为256 B,地址为8 b),置已开始接收标志;
(3)将接收到的正确字符依次放入接收缓冲寄存器中,即地址每次加1,每接收完一个字符之后清零定时器;如果在接收字符时检查到起始错误(起始位没有持续波特率所对应bit时间的一半),奇偶校验错误,或者帧错误(停止位为O),则丢弃该字符,重新同步起始位;[!--empirenews.page--]
(4)如果检测到两个字符时间间隔大于1.5个字符时间,则重置帧起始标志,把下一个接收到的字符放入接收缓冲寄存器的0x00地址,再继续步骤(3);
(5)当检测到没有字符输入且定时器第二次检测到3.5个字符时间,置协议帧接收完全标志;
(6)把接收缓冲区接收的数据作CRC校验,如果校验不正确,置帧起始标志,转到步骤(3),继续等待接收;如果是基于该接口的主Modbus协议设备,一般应设置超时时间,以避免无限等待;如果校验正确,则Re_finish发出一个脉冲,认为接收了一个在数据链路层上正确的Mod-bus协议帧。
对于帧错误(停止位为0)标志FE,奇偶校验错误标志PE,最后一个接收到的数据所在接收缓冲区中的位置Rebuf_end[7..O],对外并不必须,可以留出这些端口备用,所以用虚线表示。
2.3 输入/输出寄存器操作
接收缓冲数据寄存器和发送缓冲数据寄存器都采用双口RAM实现,这比寄存器实现要节省很多资源。为了保证对它们的操作是原子的,即为了避免同时对相同地址执行写操作,故要求当CE_Modbus置低时,外部才可以对输入输出寄存器执行写操作,此时接口内部不会对接收/输出寄存器执行任何读写操作。
2.4 发送过程
(1)在发送模式使能之前,应先处于输入/输出寄存器模式,通过Trbuf_data[7..0],Trbuf_add[7..0],Trbuf_wren把待发送的不包括两位CRC校验的Modbus协议帧从地址0x00依次写入发送缓冲寄存器中,然后使能Ld_TbNCE信号(一个时钟周期),同时存入发送缓存寄存器所装最后一个数据的地址,然后把该接口置于发送Modbus协议帧模式。
(2)发送模块先对发送数据缓冲寄存器中的所有数做CRC-16校验,然后把计算所得结果按低位在前高位在后的顺序依次放到用Ld_TbNCE信号锁存的地址的下两个地址位置处。
(3)发送模块从发送数据缓冲寄存器Ox00开始,依次读出数据并按所给的波特率发送出去,如果要求奇偶校验,则发送完数据之后加上计算所得的奇偶校验位发送出去。
(4)当发送完最后一个数据即CRC-16的高8位数据之后,Tr_finish发出一个脉冲表示发送完毕。
3 接口模块实现
3.1 波特率发生器
波特率发生器就是一个分频器,根据系统时钟分别发出位时钟(Tx_clk)和1/16位时钟(RX_clkl6)。由于系统的时钟周期可能不同,为了模块的通用性,该模块用一个类属(Generic)语句产生各种分频系数。为了保证同步设计,产生的位时钟和1/16位时钟作为控制信号在主时钟的驱动下控制其他模块。
3.2 接收模块
接收模块组包括同步滤波模块、接收机模块、接收控制模块、接收状态寄存器模块、时间标志产生模块等。
Modbus网络中设备是运行在不相关时钟上的,为了避免亚稳态现象,要求通信信号进入FPGA时通过两个级联的寄存器。异步输入信号必须在足够的时间内保持数据有效,从而保证被目标时钟域检测到,在接收端则认为最少是大于几个脉冲宽度的信号才是应该被检测到的信号,于是在接收端加入滤波模块,具体算法如下:连续3次检测到为高(或低)电平时,才往接收寄存器写入高(或低)电平,否则保持原来检测到的电平,不到3个脉冲宽度的信号被过滤。显然,同步滤波模块引入了5个时钟的延迟,但这样的延时对于Modbus协议来说可以忽略。
接收机模块是一个改进的UART接收模块,其工作流程如下:
(1)当检测到起始位时,继续读取其他位并通过移位把它们移人接收移位寄存器RSR中;
(2)当所有的数据位和停止位都接收完毕后,置RDR寄存器满标志RDRF位为1;
(3)检测停止位和奇偶校验位,如果发现错误置相关错误标志位;
(4)如果所接收数据正确,RSR中数据载入到接收数据寄存器RDR中,清除错误标志。
从Rxd_syn上进入的比特流与本地的位时钟不是同步的,为了避免可能在错误的时间读取一些位,在每个比特时间采样16次,在时钟Rx_-clkl6的每个上升沿采样,为了保证最大可行度,在理想情况下将在每比特时间中间进行采样。首先判断起始位,当检测Rxd_syn至少连续半个位时钟为低电平时,即从第一次检测到低电平之后,再连续9次检测,如果Rxd_syn为低电平的次数大于等于8次,则认为起始位到来,此时应该在起始位中间后两个Rx_clkl6处。之后每隔16个Rx_clkl6时钟周期在14,15,16个上升沿到来时分别采样,然后对3次采样结果取至少两次相等的数据作为所接收到的值,以保证接收数据的准确性。8个数据位采集完毕之后,根据Sel_parity[1..O]信号判断是否奇偶校验,如果有校验需求,则对第9个数据位的数据同样做3次采样取两次相同值作为接收到的奇偶校验位,同时计算奇偶校验结果。在停止位(不包括起始位,无校验时为第9位,有校验时为第10位)到来时,同样经过3次采样,但是只要检测到1位为高就认为停止位正确,为了减少状态机数量,可以在停止位到来时比较计算所得奇偶校验位和接收到的奇偶校验位从而判定接收数据是否奇偶校验错误。由于接收控制器一定会读取前一个数据字节并清零RDRF,所以常见的UART里的超限(overrun)错误这里并没有出现。图3为用QuartusⅡ软件自带仿真器仿真结果。[!--empirenews.page--]
3.3 发送模块
发送模块包括发送控制模块,发送机模块,发送状态寄存器模块等。
发送机模块是基于普通UART发送原理设计,其发送过程如下:
(1)等待TDRE=‘1’,即等待发送数据寄存器(TDR)为空,随后TDR中载入一个字节数据,并把TDRE清零。
(2)根据波特率设置Sel_baud[1..0]对TDR里的数据进行奇偶校验计算。
(3)把TDR里的数据放入发送移位寄存器TSR的1~8位,TSR第O位放起始位(‘O’),TSR第9位放入奇偶校验位或者停止位(‘1’)。
(4)通过对TSR右移,一位一位地发送出9位数据比特,最后发送停止位(‘1’)。
3.4 CRC模块
CRC模块包括接收CRC控制模块,发送CRC控制模块,CRC产生模块三部分。
生成CRC的过程为:
(1)将一个16位寄存器装入十六进制FFFF(全1),将之称作CRC寄存器。
(2)将报文的第一个8位字节与16位CRC寄存器的低字节异或,结果置于CRC寄存器。
(3)将CRC寄存器右移1位(向LSB方向),MSB充零,提取并检测LSB。
(4)如果LSB为0:重复步骤(3)(另一次移位);如果LSB为1:对CRC寄存器异或多项式值0xA00l(1010000000000001)。
(5)重复步骤(3)和(4),直到完成8次移位。当做完此操作后,将完成对8位字节的完整操作。
(6)对报文中的下一个字节重复步骤(2)~(5),继续此操作直至所有报文被处理完毕。
(7)CRC寄存器中的最终内容为CRC值。
这种方式计算CRC值的时间比其他方式计算CRC(比如查表法等)的时间稍微要长,但是它节省了资源,比如查表法计算CRC需要一个数组来存放所有可能的CRC结果值。图5为对数据串“010300000001”(十六进制)CRC-16运算的仿真时序图,时钟周期为50 MHz,由图可见,整个计算时间在2.5 μs内,估算一个含有240个字符的消息,CRC校验总时间约为2.5μs×(240/6)=100μs,这样长的校验计算时间对于Modbus协议来说是完全可以接受的。
4 基于该接口的MODBUS从站协处理器实现
协处理器框图如图6所示。
从站协处理器控制模块程序控制过程如下:
(1)置CE_Modbus为‘1’,把MAX485芯片信号输出置低,即控制RS 485接口芯片处于接收状态。
(2)等待一段延迟时间(RS 485接口芯片稳定时间),使能Modbus协议接口模块即置CE_Modbus为‘1’,并置接收Modbus协议帧模式。
(3)如果接收到一个完整的帧(消息),则转到步骤(4),如果没接收到一个完整的消息,一直处于等待状态。
(4)先置CE_Modbus为‘O’,再解释接收缓冲寄存器里消息,等待消息处理完毕,如果消息不是发往该从站或者为广播消息,则转到步骤(2);否则把信号输出置高,转到步骤(5)。
(5)等待一段延迟时间,使能Modbus协议接口模块即置CE_Modbus为‘1’,并置发送Modbus协议帧模式。[!--empirenews.page--]
(6)等待发送完成,转到步骤(1)。
解释模块主要由解释控制模块、分析模块、各功能码解释模块、错误功能码处理模块组成。分析模块首先分析接收消息起始两个字节,即地址码和功能码。如果地址为广播消息地址(地址为0)或者地址码和本从站地址不相等,则不处理本消息,解释控制模块发出解释完毕并置不响应信号为“1”,顶层控制模块继续处于等待接收消息状态。如果功能码为非支持功能码,则选择错误功能代码处理模块;如果为某一支持的功能码,则选择相应的功能模块解释接收消息,按照功能码要求解码(例如读/写某一指定寄存器或者线圈)。处理完之后把相应的异常码响应消息或者正常响应消息写入Modbus协议接口模块里的发送缓冲寄存器里,完毕之后通过Ld_TbNCE信号把发送缓冲寄存器锁存消息的末地址(不带CRC校验位)Trbuf_add[7..O](保证在Ld_TbNCE有效时它为末地址)存入Modbus协议接口模块,发出解释完毕信号,不响应信号置“O”,之后由顶层控制模块控制接口模块发送响应消息。对于某些功能码,比如01码和02码,03码和04码,由于对它们的解释差别很小,可以共用一个模块,达到节省资源的目的。对于特定的系统,完全可以选择某一些功能码甚至某一个功能码,而达到需求,故这里采用这种模块化方式,可以很容易在不改变其他功能模块的情况下删除不需要的功能码模块或者增加新需要的功能码模块。
该协处理器与从设备其他部分接口仅仅为双口RAM,从设备完全被映射为寄存器组的抽象,这比启用寄存器直接实现要节省逻辑资源。由于这些双口RAM是完全透明的,用户可以根据整个Modbus系统需要自定义各个寄存器的实际含义。Modbus主设备可以在任何时候随机地访问这些寄存器组。Modbus从设备控制、执行模块对这些寄存器组的访问需要寻求一种较好的方式,由于FPGA的高速度及并行机制,一般情况下可以采取轮询的机制即可满足工业实时性需求。对于某些特殊情况需要更高优先级的控制方式,也可以采取中断方式。如图7所示,可以通过双口RAM的地址线和写使能信号线进行中断检测和冲突检测:当从站协处理模块对某些特定寄存器读/写完毕之后,产生一个中断信号,对某些可能存在从站协处理器模块和从设备控制执行模块都要对其进行写操作的寄存器,如果有写操作同时发生,则从设备控制执行模块应该等待从站协处理器写完再写,以保证写操作是原子的。图8为03码应答的完整仿真时序。
图9为示波器在通信线路上检测到的波形,图9(a)展现了一系列连续帧通信实况;图9(b)展现某一应答情况,可以看出主机和从机通信电平有差异,但都在RS 485范围之内;图9(c)展现了某一帧的具体情况。
5 结语
该设计基于Altera公司FPGA,首先设计了一个可以通用于Modbus主设备和从设备的Modbus协议接口,然后基于该协议接口设计了一个通用的Modbus从设备协处理器,该接口也可以方便地用于主协议设备中。本设计通过了多款FPGA芯片的综合验证,并与WEINVIEW公司触摸屏MT-506MV和INVT公司CHF1OO-5R5G/7R5P变频器成功通信。目前该设计已在某工业EPS系统和某冲击试验台中稳定运行半年,可见其有一定应用前景。