基于MODBUS协议的CRC编码研究
- 格式:pdf
- 大小:160.74 KB
- 文档页数:3
modbus crc校验算法
Modbus CRC校验算法用于检查Modbus通信中数据的完整性。
CRC校验算法基于循环冗余校验码(CRC)。
以下是Modbus CRC校验算法的步骤:
1. 初始化一个CRC寄存器(一般为16位,初始值为0xFFFF)和一个多项式寄存器(用于执行位移和异或操作)。
2. 对要发送的数据(包括请求或响应报文)的每个字节执行以下步骤:
a. 将CRC寄存器和数据字节进行位移(右移8位)。
b. 将位移后的CRC寄存器与多项式寄存器进行异或操作。
c. 将异或操作结果反复执行,在每次操作后进行位移,直到处理完所有位。
3. 返回最终处理后的CRC寄存器的值作为校验码。
这样,接收端可以使用同样的算法对接收到的数据执行CRC校验,然后将计算得到的校验码与接收到的校验码进行比较,以判断数据的完整性。
注意:Modbus协议中的CRC校验算法可能会因实现方式或版本而有所不同,因此在实际应用中应根据具体情况进行适当的调整。
以上提供的是一种常见的Modbus CRC校验算法实现。
Modbus差错校验在Modbus串行通信中,根据传输模式(ASCII或RTU)的不同,差错校验域采用了不同的校验方法。
(1).ASCII模式在ASCII模式中,报文包含一个错误校验字段。
该字段由两个字符组成,其值基于对全部报文内容执行的纵向冗余校验(LongitudinalRedundancyCheck,LRC)计算的结果而来,计算对象不包括起始的冒号(:)和回车换行符号(CRLF)。
(2).RTU 模式在RTU 模式中,报文同样包含一个错误校验字段。
与ASCII模式不同的是,该字段由16个比特位共两个字节组成。
其值基于对全部报文内容执行的循环冗余校验(CyclicalRedundancyCheck,CRC)计算的结果而来,计算对象包括校验域之前的所有字节。
1.LRC 校验在ASCII模式中,消息是由特定的字符作为帧头和帧尾来分隔的。
一条消息必须以“冒号”(:)字符(ASCII码为0x3A)开始,以“回车换行”(CRLF)(ASCII码为0x0D 和0x0A)结束。
LRC 校验算法的计算范围为(:)与(CRLF)之间的字符。
从算法本质来说,LRC域自身为1个字节,即包含一个8位二进制数据,由发送设备通过LRC算法计算,并把计算值附到信息末尾。
接收设备在接收信息时,通过LRC算法重新计算值,并把计算值与LRC字段中接收的实际值进行比较。
若两者不同,则产生一个错误,返回一个异常响应帧。
即对报文中的所有相邻2个8位字节相加,丢弃任何进位,然后对结果进行二进制补码,计算出LRC值。
必须注意的是,计算LRC 校验码的时机,是在对报文中每个原始字节进行ASCII码编码之前,对每个原始字节进行LRC校验的计算操作。
生成LRC校验值的过程如下:(1)对消息帧中的全部字节相加(不包括起始“:”和结束符“CR-LF”),并把结果送入8位数据区,舍弃进位。
(2)由0xFF(即全1)减去最终的数据值,产生1的补码(即二进制反码)。
MODBUS的CRC校验和程序modbu协议做为一种通用协议得到了广泛的应用,它有两种传输模式:ASCII和RTU。
ASCII模式采用LRC校验,RTU模式采用CRC校验。
CRC方法错误检测域的内容是通过对消息内容进行循环冗长检测方法得出的。
使用RTU模式,消息包括了一基于CRC方法的错误检测域。
CRC域检测了整个消息的内容。
CRC域是两个字节,包含一16位的二进制值。
它由传输设备计算后加入到消息中。
接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。
CRC是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行处理。
仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。
CRC产生过程中,每个8位字符都单独和寄存器内容相或(OR),结果向最低有效位方向移动,最高有效位以0填充。
LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。
整个过程要重复8次。
在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。
最终寄存器中的值,是消息中所有的字节都执行之后的CRC值。
CRC域附加在消息的最后,添加时先是低字节然后是高字节。
故CRC的高位字节是发送消息的最后一个字节。
下面是用VB实现的CRC校验和程序:FunctionCRC16(data()AByte)AString’CRC计算函数DimCRC16LoAByte,CRC16HiAByte’CRC寄存器DimCLAByte,CHAByte’多项式码&HA001DimSaveHiAByte,SaveLoAByteDimIAIntegerDimFlagAIntegerCRC16 Lo=&HFFCRC16Hi=&HFFCL=&H1CH=&HA0ForI=0ToUBound(data)CRC16Lo=CRC16Lo某ordata(I)’每一个数据与CRC寄存器进行异或ForFlag=0To7SaveHi=CRC16HiSaveLo=CRC16LoCRC16Hi=CRC16Hi\\2’高位右移一位CRC16Lo=CRC16Lo\\2’低位右移一位If((SaveHiAnd&H1)=&H1)Then’如果高位字节最后一位为1CRC16Lo=CRC16LoOr&H80’则低位字节右移后前面补1EndIf’否则自动补0If((SaveLoAnd&H1)=&H1)Then’如果LSB为1,则与多项式码进行异或CRC16Hi=CRC16Hi某orCHCRC16Lo=CRC16Lo某orCLEndIfNe某tFlagNe某tIDimReturnData(1)AByteReturnData(0)=CRC16Hi’CRC高位ReturnData(1)=CRC16Lo’CRC低位ad=Right(\EndFunction多线程串行通讯VB源码OptionE某plicitPrivateWithEventoTet1ATetE某e.clTetPrivateWithEventoTet2ATetE某e.clTetPrivateDeclareFunctionGetTickCountLib\Dimmi,iAIntegerDoEventLoopUntilGetTickCount()-tt>tEndSubSetoTet1=NewTetE某e.clTetoTet1.lMilliec=100oTet1.StartSub(1000)SetoTet2=NewTetE某e.clTetoTet2.lMilliec=100oTet2.StartSub(1000)SetoTet1=NothingSetoTet2=NothingEndSubPrivateSubForm_Unload(CancelAInteger)oTet1.StopSuboTet2.Stop SubSetoTet1=NothingSetoTet2=NothingEndSubPrivateSuboTet1_Progre(ByVallProgreALong)Lit1.AddItemlProgre Lit1.LitInde某=Lit1.LitCount-1EndSubPrivateSuboTet2_Progre(ByVallProgreALong)recieve_meageLit2.AddItemlProgreLit2.LitInde某=Lit2.LitCount-1EndSubPrivateSubend_meage()MgBo某\通讯错误,请确认线路是否连接\错误\Ele'Label1.Caption=\开始运行\EndIfPrivateSubent_mg_Click()end_meageEndSubPrivateSubhow_mg_Click()recieve_meageEndSub如何用VB实现Modbu串行通讯在一些应用中可能需要使用诸如VB来进行上位机监控程序的开发,而Modbu协议是这类应用中首选的通讯协议;Modbu协议以其简单易用,在工业领域里已广泛的为其他第三方设备所支持。
ModBus协议中,CRC校验码计算方法Modbus协议是一个master/slave架构的协议。
有一个节点是master(主站)节点,其他使用Modbus协议参与通信的节点是slave(从站)节点。
每一个slave设备都有一个唯一的地址。
在串行网络中,只有被指定为master的节点可以启动一个命令(在以太网上,任何一个设备都能发送一个Modbus命令,但是通常也只有一个主节点设备启动指令)。
一个ModBus命令包含了打算执行的设备的Modbus地址。
所有设备都会收到命令,但只有指定位置的设备才会执行及回应指令(地址0例外,指定地址0的指令是广播指令,所有收到指令的设备都会运行,不过不回应指令)。
所有的Modbus命令包含了校验码,以确定到达的命令没有被破坏。
基本的ModBus命令能指令一个RTU改变它的寄存器的某个值,控制或者读取一个I/O端口,以及指挥设备回送一个或者多个其寄存器中的数据。
数据结构通讯消息帧ASCII消息帧(在消息中的每个8Bit 字节都作为两个ASCII字符发送) 十六进制,ASCII字符0...9,A...F消息中的每个ASCII字符都是一个十六进制字符组成每个字节的位1个起始位n个数据位,最小的有效位先发送1个奇偶校验位,无校验则无1个停止位(有校验时),2个Bit(无校验时)错误检测域LRC(纵向冗长检测)有奇偶校验无奇偶校验RTU消息帧8位二进制,十六进制数0...9,A...F消息中的每个8位域都是一个两个十六进制字符组成每个字节的位1个起始位8个数据位,最小的有效位先发送1个奇偶校验位,无校验则无1个停止位(有校验时),2个Bit(无校验时)错误检测域LRC(纵向冗长检测)有奇偶校验无奇偶校验ModBus协议中,CRC校验码计算方法为:1、预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;2、把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;3、把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;4、如果移出位为0:重复第3步(再次右移一位);如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;5、重复步骤3和4,直到右移8次,这样整个8Bit数据全部进行了处理;6、重复步骤2到步骤5,进行通讯消息帧下一个字节的处理;7、将该通讯消息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;8、最后得到的CRC寄存器内容即为:CRC码Modbus的使用限制●Modbus是在1970年为可编程逻辑控制器通信开发的,这些有限的数据类型在那个时代是可以被PLC理解的,大型二进制对象数据是不支持的;●对节点而言,没有一个标准的方法找到数据对象的描述信息,举个例子:确定一个寄存器的数据是否表示一个介于30-175度之间的温度;●由于Modbus是一个主/从协议,没有办法要求设备"报告异常"(构建在以太网的TCP/IP 协议之上,被称为open-mbus除外)- 主站节点必须循环的询问每个节点设备,并查找数据中的变化。
基于LabVIEW的Modbus协议两种校验码的实现方法陈金平,吴文英(东华大学机械工程学院,上海200051)摘要:介绍基于LabVIEW的Modbus协议两种校验码的实现方法,该方法可在基于PC机的测控系统中加以实际运用。
关键词:Modbus协议;LabVIEW;CRC校验;LRC校验Methods of Realizing the Two Check Codes of Modbus Protocol in L abVIEWCHEN Jin ping, WU Wenying(College of Mechanical Engineering, Donghua University, Shanghai 2000 51, China)Abstract:The method of realizing the two check code of modbus protocol in LabVIEW was introduced in this paper. The metho d can be used practically in MACSYM based on PC.Key words: the modbus protocol; LabVIEW; CRC checkout; LRC check out1Modbus协议简介下面仅讨论与本文有关的Modbus协议的内容。
1.1Modbus协议的数据传输方式Modbus协议定义了两种数据传输方式,即ASCII模式和RTU模式(表1、表2)。
控制器可以设置为两种传输方式(ASCII或RTU)中的任何一种,在标准的Modbus网络中进行通信。
用户可选择想要的模式,包括串口通信参数(波特率、检验方式等);在配置每个控制器的时候,在一个Modbus网络上的所有设备都必须选择相同的传输模式和串口参数。
1.2Modbus消息帧两种传输模式中(ASCII或RTU),传输设备将Modbus消息转为有起点和终点的帧,这就允许接收的设备在消息起始处开始工作,读地址分配信息,判断哪一个设备被选中(广播方式则传给所有设备),判知何时信息已完成。
Modbus通信协议是一种常用的工业控制系统通信协议,它采用客户端-服务器(Master-Slave)架构,用于实现不同设备之间的数据通信和控制。
在Modbus协议中,CRC码(Cyclic Redundancy Check)起着重要的作用,用于检测和纠正数据传输过程中的错误。
其中,CRC码的高低位顺序对于通信数据的正确性至关重要。
本文将从CRC 码的概念、计算方法和应用等方面对Modbus协议中的CRC码的高低位进行深入探讨。
一、CRC码的概念CRC码是一种通过对数据进行多项式除法运算而得出的一组校验码,用于检测数据传输中是否出现了错误。
在Modbus协议中,CRC码通常由16位二进制数字组成,通过对待发送的数据按照一定的算法进行处理而得出。
CRC码的概念包括生成多项式和计算过程。
生成多项式是确定CRC算法的关键,它决定了CRC码的计算规则和结果。
在Modbus协议中,生成多项式为0xA001,对应的二进制表示为1010 0000 0000 0001。
CRC码的计算过程是将待发送的数据与生成多项式进行模2除法,得出余数作为CRC码。
具体的计算方法将在下一节详细介绍。
二、CRC码的计算方法在Modbus协议中,CRC码的计算方法可以分为两种:高位在前和低位在前。
这两种计算方法决定了CRC码的排列顺序,对于数据的正确性和有效性具有重要影响。
1. 高位在前高位在前指的是在进行CRC码计算时,先处理数据的高位(左边)比特,然后再处理低位(右边)比特。
这种计算方法也被称为大端模式(Big Endian),在网络通信中普遍应用。
在Modbus协议中,高位在前的CRC码计算方法遵循以下步骤:(1)初始化CRC寄存器为0xFFFF;(2)将每个数据按照高位在前的顺序依次与CRC寄存器进行异或运算;(3)对每个数据进行8次位移操作,即将数据与0x01进行与运算,再将数据右移1位,并与0x7FFF进行与运算;(4)重复上述过程,直至所有数据均被处理完毕;(5)最终得到的CRC寄存器值即为高位在前的CRC码。
crc16 modbus代码CRC16 Modbus是一种常用的循环冗余校验算法,广泛应用于Modbus 通信协议中。
本文将介绍CRC16 Modbus的原理和应用,并以代码的形式展示如何进行CRC16 Modbus校验。
一、CRC16 Modbus的原理CRC全称为Cyclic Redundancy Check,即循环冗余校验。
它是一种数据校验方法,通过对数据进行一系列的数学运算,生成一个校验值,用于检测数据传输过程中是否出现错误。
CRC16 Modbus是一种基于多项式计算的CRC校验算法,它采用了16位的校验值。
CRC16 Modbus的计算过程如下:1. 首先,需要预设一个16位的寄存器,初始值为0xFFFF。
2. 将待校验的数据按照字节进行拆分,每次取出一个字节。
3. 将每个字节与寄存器的低8位进行异或运算。
4. 对寄存器的每一位进行判断,如果最低位为1,则将寄存器右移一位,并与多项式0xA001进行异或运算;如果最低位为0,则只将寄存器右移一位。
5. 重复第2步至第4步,直到所有字节都被处理完毕。
6. 最终得到的寄存器值即为CRC16 Modbus的校验结果。
二、CRC16 Modbus的应用CRC16 Modbus广泛应用于Modbus通信协议中,用于保证数据的完整性和准确性。
在Modbus通信中,发送方会计算数据的CRC16校验值,并将其附加在发送的数据中。
接收方在接收到数据后,也会进行CRC16校验,如果接收到的校验值与计算结果不一致,则说明数据可能被篡改或传输出错,接收方需要进行相应的处理。
三、CRC16 Modbus的代码示例下面是一个使用C语言实现的CRC16 Modbus校验的代码示例:```c#include <stdint.h>uint16_t crc16_modbus(uint8_t *data, uint8_t length) {uint16_t crc = 0xFFFF;uint8_t i, j;for (i = 0; i < length; i++) {crc ^= data[i];for (j = 0; j < 8; j++) {if (crc & 0x0001) {crc >>= 1;crc ^= 0xA001;}else {crc >>= 1;}}}return crc;}int main() {uint8_t data[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02}; uint16_t crc = crc16_modbus(data, sizeof(data));printf("CRC16 Modbus: 0x%04X\n", crc);return 0;}```上述代码中,crc16_modbus函数接收一个指向数据的指针和数据的长度作为参数,返回CRC16 Modbus的校验值。