modbus_rtu_crc计算方法
- 格式:doc
- 大小:22.50 KB
- 文档页数:2
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的补码(即二进制反码)。
串口通信crc校验计算
在串口通信中,CRC(循环冗余校验)是一种常用的校验方法,用于检测数据传输过程中的错误。
下面是一个简单的CRC校验计算示例,使用的是CRC-16(也称为Xmodem CRC)算法。
假设我们要发送的数据是 0x55 0x44 0x33 0x22,我们可以按照以下步骤计算CRC校验值:
1. 确定生成多项式。
在CRC-16中,常用的生成多项式是 0x1021(二进制表示为 1000000000000010000000001)。
2. 将数据左移16位,与生成多项式进行异或操作。
在本例中,数据左移后的结果为 0x55443322'00000000。
3. 将异或操作的结果与生成多项式进行模2除法,得到余数。
在本例中,余数为 0x243F(二进制表示为 1001010001111111)。
4. 将余数左移16位,与原数据拼接起来,得到CRC校验码。
在本例中,CRC校验码为 0x55443322'243F。
以上是一个简单的CRC校验计算示例,实际应用中可能需要根据具体的协议和数据进行调整。
crc计算方法CRC是循环冗余校验(Cyclic Redundancy Check)的简称,用于数据通信中检测数据传输中的错误。
其具有检验速度快、检验精度高等特点,因此广泛应用于各种通信协议中。
以下就是CRC计算方法的详细介绍。
1. CRC原理CRC校验采用除法运算和模2余数运算的方法,利用生成多项式G对数据进行校验,生成多项式G和数据D的长度一致,生成多项式G的最高次项系数为1,其余系数均为0。
在进行CRC校验时,需要将数据D在末尾填充一定位数的“0”,使其长度与生成多项式G一致。
然后将填充后的数据D除以生成多项式G,得到余数R,将余数R附加到输入数据D的末尾,形成校验码,发送至对方,对方接收到数据后也进行CRC校验,若余数R为0,则说明数据传输无误,否则说明数据传输存在错误。
2. CRC计算步骤(1)选择生成多项式G:生成多项式G的选择有多种方法,通常情况下会采用标准的CRC校验生成多项式,如CCITT标准的生成多项式为G(x)=x^16+x^12+x^5+1。
(2)将数据D在末尾补充r位“0”,其中r为生成多项式G的次数减一。
例如,若生成多项式G为x^16+x^12+x^5+1,则需要在数据D的末尾补充16+12+5=33位“0”。
(3)将填充后的数据D和生成多项式G转换为二进制,并将填充后的数据D 看作一个多项式。
(4)将生成多项式G左移至与数据D的最高位对齐,然后进行异或(XOR)运算。
(5)将异或后的结果右移一位,并将余数的最高位填充为0。
(6)重复上述步骤,直到生成多项式G无法再左移。
(7)将最终得到的余数R附加到输入数据D的末尾,形成校验码。
3. 示例以下示例采用16位的CRC校验生成多项式G(x)=x^16+x^12+x^5+1。
(1)假设输入数据D为0x1234(即0001001000110100)。
(2)将数据D末尾补充16+12+5=33位“0”,即D=000100100011010000000000000000000。
nodejs crc16modbus校验计算方法CRC16是一种循环冗余校验(Cyclic Redundancy Check)的算法,广泛应用于通信协议和数据校验中,其中CRC16 Modbus校验是Modbus协议中采用的一种CRC校验方式。
下面将介绍CRC16 Modbus校验计算方法。
CRC16 Modbus校验计算方法基于一种多项式除法算法,通过将数据进行位操作运算,从而得到CRC校验值。
以下是计算CRC16 Modbus校验的步骤:1. 初始化CRC寄存器为0xFFFF。
2. 从数据的低位开始,依次进行以下操作:2.1 将低位和CRC寄存器进行异或运算,得到结果。
2.2 将CRC寄存器右移一个位。
2.3 若上一步的结果的最低位为1,将一个特定的多项式(0xA001)与CRC寄存器进行异或运算。
2.4 重复2.1~2.3步骤,直到数据的所有位都被处理。
3. CRC寄存器的当前值即为CRC16 Modbus校验值。
下面是一个基于Node.js实现CRC16 Modbus校验的示例代码:```javascriptfunction calculateCRC16Modbus(data) {let crc = 0xFFFF;for (let i = 0; i < data.length; i++) {crc ^= data[i];for (let j = 0; j < 8; j++) {if (crc & 0x0001) {crc = (crc >> 1) ^ 0xA001; // 异或的多项式0xA001} else {crc = crc >> 1;}}}return crc;}// 示例数据:[0x01, 0x02, 0x03]const data = Buffer.from([0x01, 0x02, 0x03]);const crc = calculateCRC16Modbus(data);console.log(crc.toString(16)); // 输出CRC16 Modbus校验值(十六进制格式)```上述示例代码中,calculateCRC16Modbus函数接受一个数据数组作为参数,并返回CRC16 Modbus校验值。
MODBUS_RTU 通讯协议
1、数据传输格式:1位起始位、8位数据位、1位停止位、无奇偶校验位。
2、仪表数据格式:2字节寄存器值=寄存器数高8位二进制数+寄存器低8位二进制数
3、仪表通讯帧格式:
读寄存器命令格式:
1 2 3 4 5 6 7~8 DE 3 起始寄存器高位起始寄存器低位寄存器数高位寄存器数低位CRC 应答:
1 2 3 4~5 6~7 …M*2+2~M*2+3 M*2+4~M*2+5 DE 3 字节计数M*2 寄存器数据1 寄存器数据2…寄存器数据M CRC DE: 设备地址 (1~200)单字节
CRC: 校验字节 采用CRC-16循环冗余错误校验
举例对比说明:(LED计数器)以实际通讯数据内容为准
发送:\01\03\00\00\00\10\44\06
回收:01 03 20 01 00 08 00 8F 02 00 00 00 00 00 00 00 00 00 00 E8 00 00 00 03 55
00 00 00 00 00 00 00 00 00 00 5C 55
仪表动态数据格式
编号参数名称数据格式地址备注
1 E2PROM参数修改标志单字节定点数 0000
2 仪表类型单字节定点数 0001
3 实时测量值三字节定点数 0002
4 第一报警状态(AL1)单字节定点数 0004
5 第二报警状态(AL2)单字节定点数 0005。
MODBUS (RTU 模式)通讯规约采用RS-485, 波特率为9600BPS ,1位起始位,8位数据位,无校验,1位停止位,共10位注:消弧柜出厂时站址和通讯波特率已设置好,站址都为01。
CRC 校验权值为CRC-16=X16+X15+X5+1 1. 主站询问下行报文格式为:地址+功能码+起始地址+字长度+16位CRC 校验码 a.读命令功能码为03H从站应答上行报文格式为:地址+功能码+字长度+数据长度+16位CRC 校验码数据格式定义:地址 状态定义备注 01H 隔离刀闸位置 熔丝熔断 接触器分合 隔离刀熔丝C 熔丝B 熔丝A 接触器C 接触器B 接触器A 02H 开口谐振,开口过压过压 谐振 03H 三相PT 短线位置C 相 B 相 A 相 04H 三相金属接地位置C 相 B 相 A 相 05H三相弧光接地位置C 相B 相A 相注:0为分,1为合。
例:若设备地址为1 1.读取状态数据:主站发送:01 03 00 00 00 05 85 C9 ,其中 85 C9为CRC 校验码设备回应:01 03 05 40 00 00 00 00 B3 5D ,其中B3 5D 为CRC 校验码。
此时,刀闸处于合状态,其他状态均正常。
2. 远动复位 上位机进行远动复位,数据长度0001H ,并将接收的命令地址数据回应给上位机 主站发送:01 06 00 00 00 01 48 0A ,其中 48 0A 为CRC 校验码 设备回应:01 06 01 00 00 01 49 F6 ,其中 49 F6为CRC 校验码, 第6位为1表示远动复位完成。
03H ADR 00H 00H 00H 起始地址 05H CRC 低 CRC 高字节长CRC 校验功能码 地址03H ADR 05H 5个字节 字节长度CRC 低 CRC 高数据 CRC 校验功能码 地址。
PLC实现RTU_CRC算法PLC在使用MODBUS_RTU通信时,为了防止通信错误,都会通信帧后增加2个字节的CRC校验。
使用传统的协议宏来实现,计算CRC部分就可以交给PLC内部的相应模块;当然使用梯形图来实现CRC换算也是可行的。
下面将就使用PLC梯形图来计算CRC的结果。
一:功能块内置变量申明,对功能块的输入输出端口进行定义,为插入至主循环中对接的端口进行连接。
二:循环程序中调用CRC功能块,将功能块的“RTU_CRC16”加载入主循环中。
并连接输入输出端口。
再点击仿真按扭。
D10:输入需计算的个数;D11:计算后输出的CRC值;D12:计算后输出的CRC值进行高底字节交换(数据的大小端用)。
在仿真数据存储区D区中D2500至D2509共计十个地址中,输入需计算的数据后,在D10中指明需计算的个数。
因一个D区占用2个8位数据,故十个D区地址即20个字节,对应十六进制数#14即&20 → #14功能块内仿真详细。
使用变址寻址再加入循环移位指令。
三:CRC运算校验验证。
在PLC起始地址中输入需计算的数据,也可以在校验中根据如上图片填入“ABCDEFAAAAAABBBB1CCC1DDDEEEEFFFFABCDAAAA”,再点击“计算”,得出结果。
紫色框为换算后的数据。
可以观察到PLC梯形图计算的与CRC计算的结果都为“F713”,即得出PLC梯形图计算CRC结果完全正确。
同时如果需大端小端交换,那么可以使用OUT_2 D12输出的值。
四:程序解说D10:需计算的数据字节个数;比如图上十六进制#14对应十进制&20,即申明计算20个字节。
D11:功能块计算后输出的CRC值;D12:功能块计算后输出的CRC值进行高底字交换。
(用于大小端应用)D2500-D2509:输入计算的数据地址。
五:CRC计算方法(换算流程)1:预置1个16位的寄存器为十六进制FFFF(全1),此寄存器为CRC寄存器2:把第一个8位二进制数据与16位的CRC寄存器的低八位相异或,结果存放于CRC寄存器。
三菱PLC的MODBUSRTU的CRC计算程序编写,通讯必须掌握(点击上方红字,免费领资料)今天就说下采用RTU数据模式控制变频器,包括变频器的调频、正转、反转、停止命令的写入及运行频率的读取。
先了解下RTU帧的结构:帧头 3.5个字节的通讯时间从机地址:通讯地址0~247, 0代表广播功能码: 01H、02H、03H等数据: 2*N个字节的数据,为通讯的主要内容,包括数据地址、数据内容等。
CRC 低位: CRC校验码CRC 高位: CRC校验码帧尾: 3.5个字节的通讯时间在变频器的控制器,功能码主要用到两个03H和06H。
03H表示主机向变频器读取数据,要读取多少个数据由命令中“数据个数”而定,最多可以读取 16 个数据。
读取的参数地址必须是连续的。
每个数据占用的字节长度为 2 字节,也即一个字(word)。
以下命令格式均以 16 进制表示(数字后跟一个“H”表示 16 进制数字),一个 16 进制占用一个字节,主要作用是读取变频器的参数及工作状态,比如变频器的频率、电压、电流以及运行状态(正转、反转、停机、故障状态的监视等)06H的命令表示主机向变频器写数据,一条命令只能写一个数据,不能写多个数据。
它的作用是改变变频器的参数及工作方式,比如控制变频器正反转、停机,设定频率、转矩、加减速时间等。
我们从主机往从机发送命令后,如果发送成功,从机会返回一个回应信息,从这个返回信息中可以看出我们想要得到的东西,这里说下发送写命令06H,它的返回信息与发送命令是一样的,所以我们只有在读命令03H才用到返回信息。
下面我们举个例子说明发送信息与返回信息。
03H,从通讯地址为01的变频器,以地址0004H开始,连续读取两个数据内容就是去读0004H和0005H地址的内容。
03H从上表看出主机向从机发送命令需要知道从机的地址、功能码(命令)、数据地址、数据个数、CRC校验码,以上例子中我们知道从机的地址是01H,功能码是读03H,地址是0004H,拆分成高低位,数据个数是俩个0002H,同样拆分,最后的CRC校验码是根据以上数据计算出来的,数据发送到从机后,从机也根据信息计算一个CRC校验码,如果与主机计算的校验码一致,则通讯成功,会向从机发送一组返回信号,我们就知道了从变频器中读取的信号,例如0004H和0005H 地址的数据是5000,0,那么返回信息除了地址与命令码不变,后面的数据就变成了字节个数、数据内容了,5000的16进制是1388H,因此数据内容是高位13H,低位88H。
MODBUS RTU模式下的CRC方法
使用RTU模式,消息包括了一基于CRC方法的错误检测域。
CRC域检测了整个消息的内容。
CRC域是两个字节,包含一16位的二进制值。
它由传输设备计算后加入到消息中。
接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。
CRC是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行处理。
仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。
CRC产生过程中,每个8位字符都单独和寄存器内容相或(O R),结果向最低有效位方向移动,最高有效位以0填充。
L SB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。
整个过程要重复8次。
在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。
最终寄存器中的值,是消息中所有的字节都执行之后的C RC值。
CRC添加到消息中时,低字节先加入,然后高字节。
CRC简单函数如下:
unsigned short CRC16(puchMsg, usDataLen)
unsigned char *puchMsg ; /* 要进行CRC校验的消息 */ unsigned short usDataLen ; /* 消息中字节数 */
{
unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */ unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */ unsigned uIndex ; /* CRC循环中的索引 */
while (usDataLen--) /* 传输消息缓冲区 */
{
uIndex = uchCRCHi ^ *puchMsgg++ ; /* 计算CRC */ uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex} ; uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
}。