MODBUS允许两种传送模式:ASCII模式和RTU模式。传送模式由主机决定。在ASCII模式,消息由7位ASCII字符组成。在RTU模式,消息由8位二进制字符组成。MODBUS拥有几种不同的错误校验,ASCII模式使用LRC校验,RTU模式使用CRC校验。
下表给出ASCII模式和RTU模式的比较:
| ASCII模式(7bits) | RTU模式(8bits) | |
代码系统 | 十六进制(ASCII字符0-9,A-F) | 8位二进制 | |
位个数 | 起始位 | 1 | 1 |
数据位 | 7 | 8 | |
校验位 | 1 | 1 | |
停止位 | 1或2 | 1或2 | |
错误校验 | LRC | CRC |
在ASCII模式,每个消息帧都包括一个起始符、一个地址栏、一个功能栏、一个数据栏、一个校验栏和一个结束符。
冒号符(:)作为起始符,回车符(CR)和换行符(LF)是结束符。
ASCII模式允许在两个字符之间有最长1秒的时间间隔。
下图举例说明一个ASCII模式消息帧:
帧起始 | 地址栏 | 功能栏 | 数据栏 | 校验栏 | 帧结束 | 准备就绪 |
2字符模式 | ||||||
: | 2字符 | 2字符 | N个4字符 | 2字符 | 回车 | 换行 |
16位模式 | ||||||
: | 16位 | 16位 | N个16位 | 16位 | 回车 | 换行 |
在RTU模式,每个消息帧都包括一个地址栏、一个功能栏、一个数据栏和一个校验栏。
一帧消息传送完毕后,必须等待可发送3?个字符的时间,这一时间间隔用来同步MODBUS RTU通讯。
下图举例说明一个RTU模式消息帧:
流逝时间 | 地址栏 | 功能栏 | 数据栏 | 校验栏 | 流逝时间 |
大于发送3?个字符的时间 | (8位) 1字符 | (8位) 1字符 | (8位) 1字符 | (8位) 1字符 | 大于发送3?个字符的时间 |
错误检查包括硬件奇偶校验、ASCII模式的LRC校验和RTU模式的CRC校验.
偶校验
数据位与校验位的和为偶数。
奇校验
数据位与校验位的和为奇数。
LRC校验数与ASCII模式消息帧的地址栏、功能栏、数据栏的总和为零。
在计算时,不包括起始符冒号(:)和结束符回车(CR)与换行(LF)。
下面给出LRC的计算程序:
static unsigned char LRC(auchMsg, usDataLen)
unsigned char *auchMsg ; /* message to calculate LRC upon */
unsigned short usDataLen ; /* quantity of bytes in message */
{
unsigned char uchLRC = 0 ; /* LRC char
initialized */
while (usDataLen––) /* pass through
message buffer */
uchLRC += *auchMsg++ ; /* add buffer byte
without carry */
return ((unsigned char)(–((char)uchLRC)))
; /* return twos complement */
}
产生CRC校验值的过程
1、
调用一个16位寄存器,写入十六进制数FFFF。我们称这一寄存器为CRC寄存器。
2、
异或消息帧的第一个8位数,结果存在CRC寄存器。
3、
将CRC寄存器右移一位,最高位(MSB)填零,然后检查移出位。
4、
如果移出位为0,则重复第3步(继续右移);
如果移出位为1,CRC寄存器异或十六进制数A0001;
5、
重复步骤3、4直到8次右移结束。
6、
异或消息帧的下一个8位数,结果存在CRC寄存器。
7、
重复步骤3~6直到消息帧的所有数据被处理。
8、
最后得到的2字节数(16位)就是CRC校验值。
下面给出CRC的计算程序:
//***CRC Calculation for MODBUS Protocol for VC++***//
//数组snd为地址等传输字节,num为字节数//
unsigned int mb_crc(BYTE *snd,int num)
{ int i,j;
unsigned int c,crc=0xFFFF
for (i=0;i
{ c=str & 0x00FF;
crc^=c;
for(j=0,j<8,j++)
{ if (crc & 0x0001)
{crc>>=1;crc^=0xA001;}
else crc>>=1
}
}
return(crc);
}
文章评论(0条评论)
登录后参与讨论