编码比较

  • 格式:docx
  • 大小:37.11 KB
  • 文档页数:6

个人档案
呢称:azmao 文章(30) 访问(73291) 评论(50) 投票(5) 订阅本

介绍:azmao
全部博文:
2009年 - 6月2月
2008年 - 10月9月8月7月6月5月 查看全部博文

博客首页

仪表的现场总线通讯--modbus(4) [工业控制] 发布时间:2008-06-05 11:17:25
1
数据传送模式

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
1.1 ASCII模式消息帧
在ASCII模式,每个消息帧都包括一个起始符、一个地址栏、一个功能栏、一个数据栏、一
个校验栏和一个结束符。

冒号符(:)作为起始符,回车符(CR)和换行符(LF)是结束符。
ASCII模式允许在两个字符之间有最长1秒的时间间隔。
下图举例说明一个ASCII模式消息帧:

帧起始
地址栏 功能栏 数据栏 校验栏 帧结束
准备就绪

2字符模式

2字符 2字符 N个4字符 2字符 回车
换行

16位模式

16位 16位 N个16位 16位 回车 换行
1.2 RTU模式消息帧
在RTU模式,每个消息帧都包括一个地址栏、一个功能栏、一个数据栏和一个校验栏。
一帧消息传送完毕后,必须等待可发送3?个字符的时间,这一时间间隔用来同步MODBUS
RTU通讯。

下图举例说明一个RTU模式消息帧:

流逝时间
地址栏 功能栏 数据栏 校验栏
流逝时间

大于发送3?个字符的时间 (8位) 1字符 (8位) 1字符 (8位) 1字符 (8位) 1字符 大于发送3?个字符的时间
1.3 错误检查
错误检查包括硬件奇偶校验、ASCII模式的LRC校验和RTU模式的CRC校验.
1.3.1
硬件奇偶校验

偶校验
数据位与校验位的和为偶数。
奇校验
数据位与校验位的和为奇数。
1.3.2
ASCII模式的LRC校验

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 */
}
1.3.3
RTU模式的CRC校验

产生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 intmb_crc(BYTE *snd,intnum)
{ inti,j;
unsigned intc,crc=0xFFFF
for (i=0;i
{ c=str[i] & 0x00FF;
crc^=c;
for(j=0,j<8,j++)
{ if (crc& 0x0001)
{crc>>=1;crc^=0xA001;}
else crc>>=1
}
}
return(crc);
}