AB 脚本modbusCRC验证查表语言及格式
Modbus差错校验
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校验和程序
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格式
MODBUS格式2、 Modbus RTU报文基本格式起始应有不小于3.5个字符的报文间隔2.1 Modbus命令简介注:下面对于各请求命令的“应答格式”的描述是指命令被正确执行时的应答格式。
若CPU接收到错误的命令或者命令被执行错误,则返回的应答帧中“功能码”部分变为如下数据:功能码的最高位置1后得到的数据。
比如功能码为01,若响应错误,则返回的功能码为0x81。
2.1.1 功能码01:读线圈(开关量输出)请求格式:正确应答格式:2.1.2 功能码02:读输入状态(开关量输入)请求格式:正确应答格式:2.1.3 功能码03:读保持寄存器(模拟量输出)请求格式:正确应答格式:2.1.4 功能码04:读输入寄存器(模拟量输入)请求格式:正确应答格式:2.1.5 功能码05:写单线圈(开关量输出)请求格式:注:强制值= 0xFF00,则置线圈为ON;强制值=0x0000,则置线圈为OFF。
应答格式:若设置成功,原文返回2.1.6 功能码06:写单保持寄存器(模拟量输出)请求格式:应答格式:若设置成功,原文返回2.1.7 功能码15:写多线圈(开关量输出)请求格式:正确应答格式:2.1.8 功能码16:写多保持寄存器(模拟量输出)请求格式:正确应答格式:2.2 Modbus协议中的CRC校验算法在Modbus RTU协议中,使用CRC作为帧的校验方式。
下面是用C编写的两种CRC算法:2.2.1 直接计算CRC/* 参数:chData ―― const BYTE*,指向待校验数据存储区的首地址uNO ――待校验数据的字节个数返回值:WORD型,计算出的CRC值。
*/WORD CalcCrc(const BYTE* chData, WORD uNo){WORD crc=0xFFFF;WORD wCrc;UCHAR i,j;for (i=0; i<="" p="">{crc ^= chData[i];for (j=0; j<8; j++){if (crc & 1){crc >>= 1;crc ^= 0xA001; }elsecrc >>= 1;}}wCrc=( (WORD)LOBYTE(crc) )<<8;wCrc=wCrc|( (WORD)HIBYTE(crc) );return (wCrc);}2.2.2 查表快速计算CRC/* 高字节CRC表 */const UCHAR auchCRCHi[] ={0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ;/* 低字节CRC表 */const UCHAR auchCRCLo[] ={0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;/* 参数:puchMsg ―― const BYTE*,指向待校验数据存储区的首地址usDataLen ――待校验数据的字节个数返回值:WORD型,计算出的CRC值。
modbus crc 查表法与计算法
Modbus是一种用于串行通信的协议,通常用于工业控制系统中的设备之间的通信。
在Modbus协议中,通信的数据经常需要进行CRC (循环冗余校验)校验以确保数据的准确性。
在实际应用中,我们可以通过查表法或计算法来计算Modbus协议中的CRC校验值。
本文将介绍Modbus CRC的查表法和计算法,并对这两种方法进行比较和分析。
一、Modbus CRC的概念及应用Modbus通信协议是一种用于工业控制系统的通信协议,它规定了设备之间的数据通信格式和规则。
在Modbus协议中,通信的数据需要进行CRC校验以确保数据的完整性和准确性。
CRC校验是一种通过对数据进行处理得到固定长度的校验码,用于校验数据传输的正确性的技术。
Modbus协议中的CRC校验值通常是16位的,可以通过CRC计算器进行计算,并将计算得到的校验值附加到数据传输中。
接收端收到数据后,同样可以通过计算CRC校验值来验证数据的正确性。
二、Modbus CRC的查表法1. 查表法是一种通过预先计算出CRC校验值并存储在表中,然后在实际使用时直接查表得到CRC校验值的方法。
对于Modbus协议中的CRC校验,可以使用一个256个元素的查表来进行计算。
2. 查表法的优点是计算速度快,适用于嵌入式系统或资源有限的设备。
由于CRC校验是通过查表得到的,因此不需要进行复杂的计算,可以节省系统资源和计算时间。
3. 但是查表法的缺点是需要额外的存储空间来存储CRC校验值的查表,对于一些资源有限的设备可能会造成存储空间的浪费。
三、Modbus CRC的计算法1. 计算法是一种通过数学计算来得到CRC校验值的方法。
对于Modbus协议中的CRC校验,可以使用多项式除法来进行计算。
2. 计算法的优点是不需要额外的存储空间来存储查表,因此不会造成存储空间的浪费。
而且计算法可以适用于任何系统,不受资源限制的影响。
3. 但是计算法的缺点是计算速度相对较慢,特别是对于资源有限的嵌入式系统或单片机来说,可能会影响系统的性能。
modbus协议各表详细说明
10 指令发送数据格式举例为:
发送数据 01
10
0000
0002
04
0000 0000
CRC
含义
地址
连续下写 连续下写 总字节 指令
的首地址 数据个数 数据个数×2
下写的数据
校验码
—1—
各型号仪表详细说明 XM708 XM708P XM808/908 XM808P/908P XMH XMT XMG/XMG-M
警不存在,为 1 表示报警成立。
7
6
5
4
3
2
1
0
0
0
0
0
AL4 报警 AL3 报警 AL2 报警 AL1 报警
—8—
XMG/XMG-M
1、03 指令参数地址 参数名 AL1 AL2 AL3 AL4 dLY1 dLY2 dLY3 dLY4 Alo1 Alo2 Alo3 Alo4 dF1 dF2 dF3 dF4 PF CHO Bout Loc1 Addr bAud Sn dip
diP
小数点位置
diL
下限显示限值
0BH
CSC
冷端补偿参数
1BH
0CH
SF
超调抑制参数
1CH
0DH
SVL
给定值下限限定
1DH
diH
上限显示限值
Sc
平移修正参数
0EH
SVH
给定值上限限定
1EH
10H
曲线运行状态
16H
(2)曲线设置参数
参数
参数含义
通讯地址
C01
第一段曲线的设定值
1BH
T01
第一段曲线的运行时间
参数含义 平移修正参数 控制输出方式 控制输出下限 控制输出上限 报警输出定义参数 正反作用选择
modbus校验码类型表示方式
《Modbus校验码类型表示方式:全面解析》1. 前言在现代工业控制系统中,Modbus协议是一种广泛应用的通信协议。
在Modbus通信过程中,校验码类型表示方式是一个重要的概念,对于确保通信的准确性和可靠性至关重要。
本文将从深度和广度两个方面对Modbus校验码类型表示方式进行全面解析。
2. 什么是Modbus校验码类型表示方式Modbus是一种串行通信协议,广泛应用于工业自动化领域。
在Modbus通信过程中,校验码类型表示方式用于确认数据在传输过程中的准确性,以及检测是否有误码。
常见的校验码类型包括奇偶校验、CRC校验和LRC校验等。
3. 奇偶校验的表示方式奇偶校验是一种最简单的校验码类型表示方式。
在奇偶校验中,数据位的个数为奇数或偶数,通过计算数据位中1的个数来确定校验位的数值。
如果数据位中1的个数为奇数,则校验位被设置为0;如果数据位中1的个数为偶数,则校验位被设置为1。
奇偶校验可以检测出单个位的错误,但不能检测出两个或多个位的错误。
4. CRC校验的表示方式CRC校验是一种更为复杂和高效的校验码类型表示方式。
CRC校验使用多项式运算来生成校验码,通过计算数据位的余数来确定校验位的数值。
CRC校验可以检测出更多种类的错误,包括单个位、两个或多个位的错误,以及其他类型的错误。
在Modbus通信中,CRC校验被广泛应用于数据的校验和确认。
5. LRC校验的表示方式LRC校验是一种线性冗余校验的类型表示方式。
在LRC校验中,对数据位进行逐位累加,并取累加和的补码作为校验位的数值。
LRC校验通常被用于字符流的校验和确认,无法检测出位的错误,但可以用于检测出其他类型的错误。
6. 总结与回顾在Modbus通信中,校验码类型表示方式是确保数据传输准确性和可靠性的关键环节。
奇偶校验、CRC校验和LRC校验是常见的校验码类型表示方式,各自具有不同的特点和适用范围。
在实际应用中,需要根据具体的通信环境和需求来选择合适的校验码类型表示方式,以确保通信的稳定和可靠。
Modbus的CRC校验实验
Modbus的CRC校验实验Modbus的CRC校验实验表述Name : "CRC-16/MODBUS"Width : 16Poly : 8005Init : FFFFRefIn : TrueRefOut : TrueXorOut : 0000Check : ?先参考⼀些⼚家给的MODBUS校验程序const unsigned char auchCRCHi[] = {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ;const unsigned char auchCRCLo[] = {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;//crc low byte in high 8 bitunsigned short Modbus_CRC16(unsigned char *Buff_addr,unsigned short len){unsigned char uchCRCHi = 0xFF; // CRC⾼字节的初始化unsigned char uchCRCLo = 0xFF; // CRC低字节的初始化unsigned short uIndex; // CRC查找表的指针while (len--){uIndex = uchCRCHi ^ *Buff_addr++; // 计算CRCuchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];uchCRCLo = auchCRCLo[uIndex];}return(uchCRCHi <<8 | uchCRCLo);}//crc high byte in high 8 bitunsigned short Modbus_CRC16_2(unsigned char *Buff_addr,unsigned short len){unsigned char uchCRCHi = 0xFF ;unsigned char uchCRCLo = 0xFF ;unsigned uIndex ;while (len--){uIndex = uchCRCLo ^ *Buff_addr++ ; /* calculate the CRC*/uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex] ;uchCRCHi = auchCRCLo[uIndex] ;}return (uchCRCHi << 8 | uchCRCLo) ;}由上以程序,可看到使⽤的⽅法是直驱表法,⽽这个⽣成的表却与正向poly直接计算⽣成的表是不⼀致的。
modbus_CRC校验
最详细易懂的CRC-16校验原理(附源程序)标签:crc校验计算方法详细易懂源程序2010-10-29 09:39阅读(8048)评论(0)最详细易懂的CRC-16校验原理(附源程序)1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。
2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。
例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。
标准CRC生成多项式如下表:名称生成多项式简记式* 标准引用CRC-4 x4+x+1 3 ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8 x8+x6+x4+x3+x2+x1 0x5ECRC-12 x12+x11+x3+x+1 80FCRC-16 x16+x15+x2+1 8005 IBM SDLCCRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCSCRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCSCRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP3、CRC-16校验码的使用:现选择最常用的CRC-16校验,说明它的使用方法。
根据Modbus协议,常规485通讯的信息发送形式如下:地址功能码数据信息校验码1byte 1byte nbyte 2byteCRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。
例如:信息字段代码为: 1011001,校验字段为:1010。
modbus标准crc校验算法
文章标题:深入探讨Modbus标准CRC校验算法在工业自动化领域,Modbus通信协议是一种应用广泛的串行通信协议,其中的CRC校验算法对于数据完整性的验证起着至关重要的作用。
本文将围绕Modbus标准CRC校验算法展开深入探讨,以便读者能够更全面地了解该算法的原理和应用。
1. 什么是Modbus通信协议?Modbus是一种用于工业领域的通信协议,它通常用于连接各种自动化设备和控制系统,如PLC(可编程逻辑控制器)、传感器、执行器等。
Modbus协议可以通过串行通信或以太网进行数据传输,实现设备之间的数据交换和控制命令的传输。
2. CRC校验算法的作用及原理CRC(Cyclic Redundancy Check)是循环冗余校验的缩写,是一种通过对数据进行计算并附加校验值来验证数据完整性的算法。
在Modbus通信中,CRC校验算法被用于检测通信数据在传输过程中是否发生了误码或数据损坏。
Modbus标准CRC校验算法采用的是CRC-16-Modbus算法,它基于多项式计算和位操作来生成16位的校验码。
在发送端,数据帧的CRC校验码由发送设备计算并附加在数据帧的末尾;在接收端,接收设备也对接收到的数据帧进行CRC校验,来验证接收到的数据是否完整和正确。
3. Modbus标准CRC校验算法的具体计算方法Modbus标准CRC校验算法的计算方法比较复杂,需要对数据帧进行按位运算和多项式计算。
需要对每个字节的数据进行移位和异或运算,然后再进行一系列的位操作和多项式运算,最终得到16位的CRC校验码并附加在数据帧的末尾。
4. Modbus标准CRC校验算法的应用场景Modbus标准CRC校验算法广泛应用于工业自动化领域的数据通信和控制系统中。
它能够有效地验证数据传输的完整性和准确性,确保通信数据的可靠性和稳定性。
在 PLC、传感器、执行器等设备之间的数据交换和控制指令传输中,CRC校验算法能够及时发现并纠正数据错误,保障系统的正常运行。
crc校验查表法原理
crc校验查表法原理CRC校验是一种常用的错误检测方法,通过对数据进行计算生成校验码,可以快速检测出数据传输过程中是否出现错误。
而CRC校验的查表法则是其中一种较为高效的实现方式。
本文将详细介绍CRC 校验查表法的原理和实现方法。
一、CRC校验概述CRC(Cyclic Redundancy Check)校验是一种循环冗余校验方法,常用于数据通信领域。
它通过对数据进行多项式除法运算,得到余数作为校验码。
接收方根据发送方传输的数据和校验码进行计算,如果计算出的余数为0,则认为数据传输正确;否则,认为数据传输出现错误。
二、CRC校验查表法原理CRC校验查表法是CRC校验的一种高效实现方式。
它通过预先计算出一张查表,将多项式除法运算转化为简单的查表操作,从而提高计算效率。
1. 多项式转化为二进制将CRC校验中使用的多项式转化为二进制形式。
例如,CRC-8校验中使用的多项式为x^8 + x^2 + x + 1,将其转化为二进制形式为100000111。
2. 初始化查表根据CRC校验的位数,初始化一个256个元素的查表。
以CRC-8为例,查表长度为256个元素。
3. 生成查表从0到255的每一个数值,通过以下步骤生成查表的每个元素:(1)将当前数值左移8位,作为除数。
(2)循环8次,每次判断除数最高位是否为1:- 如果最高位为1,则将除数左移一位,并与多项式进行异或操作。
- 如果最高位为0,则将除数左移一位。
(3)将计算结果作为查表的当前元素。
4. CRC校验过程发送方在发送数据前,根据多项式和查表生成校验码。
接收方在接收到数据后,根据接收到的数据和查表进行校验。
(1)发送方:- 将数据按位划分为若干字节。
- 初始化CRC校验值为0。
- 依次取出每个字节,将其与CRC校验值进行异或操作。
- 根据异或的结果,在查表中查找对应的值,并更新CRC校验值。
- 重复以上步骤,直到所有字节处理完毕。
- 最终的CRC校验值即为校验码,将其附加到数据后发送。
MODBUS格式
2、 Modbus RTU报文基本格式2.1 Modbus命令简介注:下面对于各请求命令的“应答格式”的描述是指命令被正确执行时的应答格式。
若CPU接收到错误的命令或者命令被执行错误,则返回的应答帧中“功能码”部分变为如下数据:功能码的最高位置1后得到的数据。
比如功能码为01,若响应错误,则返回的功能码为0x81。
2.1.1 功能码01:读线圈(开关量输出)请求格式:正确应答格式:2.1.2 功能码02:读输入状态(开关量输入)请求格式:正确应答格式:2.1.3 功能码03:读保持寄存器(模拟量输出)请求格式:正确应答格式:2.1.4 功能码04:读输入寄存器(模拟量输入)请求格式:正确应答格式:2.1.5 功能码05:写单线圈(开关量输出)请求格式:注:强制值= 0xFF00,则置线圈为ON;强制值=0x0000,则置线圈为OFF。
应答格式:若设置成功,原文返回2.1.6 功能码06:写单保持寄存器(模拟量输出)请求格式:应答格式:若设置成功,原文返回2.1.7 功能码15:写多线圈(开关量输出)请求格式:正确应答格式:2.1.8 功能码16:写多保持寄存器(模拟量输出)请求格式:正确应答格式:2.2 Modbus协议中的CRC校验算法在Modbus RTU协议中,使用CRC作为帧的校验方式。
下面是用C编写的两种CRC算法:2.2.1 直接计算CRC/* 参数:chData ―― const BYTE*,指向待校验数据存储区的首地址uNO ――待校验数据的字节个数返回值:WORD型,计算出的CRC值。
*/WORD CalcCrc(const BYTE* chData, WORD uNo){WORD crc=0xFFFF;WORD wCrc;UCHAR i,j;for (i=0; i<uNo; i++){crc ^= chData[i];for (j=0; j<8; j++){if (crc & 1){crc >>= 1;crc ^= 0xA001; }elsecrc >>= 1;}}wCrc=( (WORD)LOBYTE(crc) )<<8;wCrc=wCrc|( (WORD)HIBYTE(crc) );return (wCrc);}2.2.2 查表快速计算CRC/* 高字节CRC表 */const UCHAR auchCRCHi[] ={0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ;/* 低字节CRC表 */const UCHAR auchCRCLo[] ={0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;/* 参数:puchMsg ―― const BYTE*,指向待校验数据存储区的首地址usDataLen ――待校验数据的字节个数返回值:WORD型,计算出的CRC值。
modbus协议格式
modbus协议格式Modbus协议格式。
Modbus协议是一种用于工业自动化领域的通信协议,它是一种串行通信协议,用于在不同设备之间进行数据传输。
Modbus协议格式定义了数据的传输格式和通信规则,保证了不同设备之间的数据交换的准确性和可靠性。
本文将介绍Modbus协议格式的相关内容,包括数据帧格式、功能码、地址表示等内容。
1. 数据帧格式。
Modbus协议使用了一种简单的数据帧格式,包括地址域、功能码、数据域和校验域。
其中,地址域用于表示设备地址,功能码用于表示数据的读写类型,数据域用于存储具体的数据内容,校验域用于检验数据的准确性。
数据帧格式简单清晰,易于实现和解析,是Modbus协议的一大特点。
2. 功能码。
Modbus协议定义了一系列的功能码,用于表示不同的数据读写类型。
常用的功能码包括读保持寄存器、写单个寄存器、读输入寄存器等。
不同的功能码对应着不同的数据操作,可以满足不同设备之间的数据交换需求。
3. 地址表示。
在Modbus协议中,设备地址是一个重要的概念。
每个设备都有一个唯一的地址,用于在总线上进行识别和通信。
地址表示的方式包括十进制表示和十六进制表示,不同的设备可以根据需要选择合适的地址表示方式。
4. 数据传输规则。
Modbus协议规定了数据的传输规则,包括数据的封装、传输顺序、校验方法等。
在数据传输过程中,需要保证数据的完整性和准确性,避免数据丢失和损坏。
传输规则的严格执行保证了数据的可靠传输。
5. 应用范围。
Modbus协议被广泛应用于工业自动化领域,包括工业控制、仪器仪表、传感器、执行器等设备之间的通信。
它简单易懂的数据帧格式和丰富的功能码使得它成为工业领域的通信标准之一。
总结。
Modbus协议格式是一种简单而有效的通信协议,它定义了数据的传输格式和通信规则,保证了不同设备之间的数据交换的准确性和可靠性。
了解和掌握Modbus协议格式对于工业自动化领域的从业人员来说是非常重要的。
modbus协议功能码及格式
modbus协议功能码及格式1、“01”读取线圈状态发送:功能代码1字节 0x01起始地址2字节0x0000~0xFFFF 线圈数量2字节1~2000(0x7D0)接收:功能代码1字节 0x01字节数1字节 N线圈状态n字节n = N/N+1N=读取线圈个数 / 8 ,如果余数不为0则N=N+1出错时的返回:功能代码1字节 0x81错误代码1字节 01/02/03/04例子:返送:01 01 00 00 00 19 FD C0 即:读取25个线圈的状态返回:01 01 04 0F 03 80 01 A8 C5FC BN N1 N2 N3 N4 CRC,N1为前8位的状态以此内推。
2、“02”读取输入状态发送:功能代码1字节 0x02起始地址2字节0x0000~0xFFFF 输入点数量2字节1~2000(0x7D0)接收:功能代码1字节 0x02字节数1字节 N输入点状态n字节n = N/N+1N=读取输入点个数 / 8 ,如果余数不为0则N=N+1出错时的返回:功能代码1字节 0x82错误代码1字节 01/02/03/04例子:发送:01 02 00 00 00 19 B9 C0读25个输入线圈的状态返回:01 02 04 00 00 00 00 FB E2FC BN N1 N2 N3 N4 CRC3、“03”保持型寄存器读取发送:功能代码1字节 0x03起始地址2字节0x0000~0xFFFF 寄存器数量2字节1~125(0x7D)接收:功能代码1字节 0x03字节数1字节 2*N寄存器值 N*2字节N=寄存器数量出错时的返回:功能代码1字节 0x83错误代码1字节 01/02/03/04例子:发送:01 03 00 00 00 03 05 CB读3个寄存器里面的值返回:01 03 06 01 2C 01 2C 01 2C 71 1A返回3个寄存器的值,每个寄存器的值有2个BYTE组成4、“05”写单一线圈发送:功能代码1字节 0x05线圈地址2字节 0x0000~0xFFFF 写入值2字节 0x0000或0xFF00 接收:功能代码1字节 0x05线圈地址2字节 0x0000~0xFFFF 写入值2字节 0x0000或0xFF00 出错时的返回:功能代码1字节 0x85错误代码1字节 01/02/03/04例子:发送:01 05 00 00 FF 00 8C 3A写单个线圈的值,把地址为0的线圈置一。
Modbus通信协议中CRC校验的快速C语言算法
当 RT U 模式用在 字符格式中 时 , 错误校 验域 包含一 个 16 比特位 , 相当两个 8 位字节的 校验值 。 校验值 是对信息 内容计 算的 CRC 结果 。 CRC 域 被附 加在 信息 最后 , 作 为信 息最 后的 域 。CRC 域内低字 节被 附加 在先 , 跟 在后 面的 是高 字节 , CRC 高字节被设置为信息的最后 。 3.2 选择 CRC 生成器多项式
地址 0 被用在通信地址中 , 这个通 信地址 所有的从 地址都 认识 。 当 M odbus 协议被用在高 级的网络上 时 , 通 信不能 进行 , 也不能用别的方法代替 。 例如 , M odbus 升级版能用一个被全球 共享的数据库 。 这个数据库能被任意更改 。 2.4 功能域的设置
信息框架的功能 代码 域包 括两 个字 符的 ASCI I 或八 个字 节的 RT U 。 有效代码范围从 1 到 255(十 进制)。 当然 , 一些代 码能适用所有的 M odicon 控 制器 , 但是一 些代码 只可用 于某些 模式 , 并且还有一些被保留供 以后使 用 。 各信 息传送各 子设备 时 , 功能代码域告 诉子 设备 所要 进行 哪种 运行 类别 。 例如 , 读 一组不连续线圈或输入端的 开/ 关状 态 ;读 一组寄 存器的 内容 ; 写指定线圈或寄存器 ;或者允 许装载 , 记录 , 或 在子设备 中验证 程序 。 当子设备反应给主设备时 , 要用 代码域 功能显示 其他的 正常反应或一些错误发生(称为异 常反应)。 作为 正常响 应 , 子 设备简单应答原来的功能代码 。 作 为异常 反应 , 子设备 返回一 个代码 , 这个代码 等价 于原先 的功 能代码(在字 节中 最有 效的 设置)。 除了对例 外响应 的功 能代 码修 改外 , 子 设备 在响 应信 息数据域里设置 一个唯 一的 代码 。 这 样告 诉主 设备 发生 了哪 类错误 , 和错误的原因 。 3 RTU 错误校验域的内容 3.1 CRC 校验域的次序
MODBUS RTU CRC校验程序
* 将数据D10开始放入D2中与CRC异或运算,算完后用V1加1进入下字节运算
D10→D50
M8000 26 MOV D10V1 发送数据 起始位 D2 运算辅助 寄存器
1应用:M10→M100
WXOR
D2 K4M10 运算辅助 CRC寄存 寄存器 器起始位
K4M10 CRC寄存 器起始位
* 从起始数据D10开始的每个8位数据均要从低位开始逐位进行异或运算 39 FOR K8
K4M10 CRC寄存 器起始位
CJ * 每一位异或运算完后不管结果值是否为1,均要右移一位,高位用0填补 M10 62 CRC寄存 器起始位
1应用:M10→M100 1应用:M10→M100
P2
SFTR
M0 M10 K16 填补用0值 CRC寄存 器起始位
K1
* 如上进行1个8位数据的8次循环异或运算 P2 72 * 所有要发送的数据发送数据运算完成,产生低位K2M10,高位K2M18的CRC校验码 78 NEXT INC V1 NEXT
* 计算CRC校验码前将数据进位V1复位,设定一个值全为1的CRC寄存器K4M10 M8000 0 MOV K0 V1
Modbus协议中CRC校验和LRC校验
CRC 的生成循环冗余校验(CRC) 域为两个字节,包含一个二进制16 位值。
附加在报文后面的CRC 的值由发送设备计算。
接收设备在接收报文时重新计算CRC 的值,并将计算结果于实际接收到的CRC值相比较。
如果两个值不相等,则为错误。
CRC 的计算, 开始对一个16位寄存器预装全1. 然后将报文中的连续的8位子节对其进行后续的计算。
只有字符中的8个数据位参与生成CRC 的运算,起始位,停止位和校验位不参与CRC 计算。
CRC 的生成过程中,每个 8–位字符与寄存器中的值异或。
然后结果向最低有效位(LSB) 方向移动(Shift) 1位,而最高有效位(MSB) 位置充零。
然后提取并检查LSB:如果LSB 为1,则寄存器中的值与一个固定的预置值异或;如果LSB 为 0,则不进行异或操作。
这个过程将重复直到执行完8 次移位。
完成最后一次(第8 次)移位及相关操作后,下一个8位字节与寄存器的当前值异或,然后又同上面描述过的一样重复8 次。
当所有报文中子节都运算之后得到的寄存器中的最终值,就是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 寄存器异或多项式值0xA001 (1010 0000 0000 0001).5. 重复步骤3 和 4,直到完成8 次移位。
当做完此操作后,将完成对8位字节的完整操作。
6. 对报文中的下一个字节重复步骤2 到5,继续此操作直至所有报文被处理完毕。
7. CRC 寄存器中的最终内容为CRC 值.8. 当放置CRC 值于报文时,如下面描述的那样,高低字节必须交换。
Modbus通讯格式详解教程
Modbus通讯协议格式Modbus通讯协议格式为主机发送:[开始] [从机地址] [功能代码] [起始寄存器地址高8 位] [低8位] [写单寄存器数高8 位] [低8 位] [LRC 校验码] [CR] [LF]所以本文依据格式逐个介绍解疑:[开始] 为:[从机地址] 为已知;[功能代码] 的名称、作用将在下面介绍;[寄存器地址]分配及寄存器中值的含义将在下面介绍;[LRC 校验码] 可以用Commix软件算出来,详细请参考Commix相关资料;最后是实例加以说明验证。
功能码名称作用01 读取线圈状态取得一组逻辑线圈的当前状态(ON/OFF)02 读取输入状态取得一组开关输入的当前状态(ON/OFF)03 读取保持寄存器在一个或多个保持寄存器中取得当前的二进制值04 读取输入寄存器在一个或多个输入寄存器中取得当前的二进制值05 强置单线圈强置一个逻辑线圈的通断状态06 预置单寄存器把具体二进值装入一个保持寄存器07 读取异常状态取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定08 回送诊断校验把诊断校验报文送从机,以对通信处理进行评鉴09 编程(只用于484)使主机模拟编程器作用,修改PC从机逻辑10 控询(只用于484)可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送11 读取事件计数可使主机发出单询问,并随即判定操作是否成功,尤其是该命令或其他应答产生通信错误时12 读取通信事件记录可是主机检索每台从机的ModBus事务处理通信事件记录。
如果某项事务处理完成,记录会给出有关错误13 编程(184/384 484 584)可使主机模拟编程器功能修改PC从机逻辑14 探询(184/384 484 584)可使主机与正在执行任务的从机通信,定期控询该从机是否已完成其程序操作,仅在含有功能13的报文发送后,本功能码才得发送15 强置多线圈强置一串连续逻辑线圈的通断16 预置多寄存器把具体的二进制值装入一串连续的保持寄存器17 报告从机标识可使主机判断编址从机的类型及该从机运行指示灯的状态18 (884和MICRO 84)可使主机模拟编程功能,修改PC状态逻辑19 重置通信链路发生非可修改错误后,是从机复位于已知状态,可重置顺序字节20 读取通用参数(584L)显示扩展存储器文件中的数据信息21 写入通用参数(584L)把通用参数写入扩展存储文件,或修改之22~64 保留作扩展功能备用65~72 保留以备用户功能所用留作用户功能的扩展编码73~119 非法功能120~127 保留留作内部作用128~255 保留用于异常应答保护器Modbus 通讯协议:半双工RS485 口,传输距离≤1200 米。