EDN首页   博客首页

日志档案

发表于 2008/6/5 11:17:25

2

标签: 无标签

仪表的现场总线通讯--modbus(4)

1       数据传送模式

MODBUS允许两种传送模式:ASCII模式和RTU模式。传送模式由主机决定。在ASCII模式,消息由7ASCII字符组成。在RTU模式,消息由8位二进制字符组成。MODBUS拥有几种不同的错误校验,ASCII模式使用LRC校验,RTU模式使用CRC校验。

下表给出ASCII模式和RTU模式的比较:

 

ASCII模式(7bits

RTU模式(8bits

代码系统

十六进制(ASCII字符09AF

8位二进制

位个数

起始位

1

1

数据位

7

8

校验位

1

1

停止位

12

12

错误校验

LRC

CRC

1.1    ASCII模式消息帧

ASCII模式,每个消息帧都包括一个起始符、一个地址栏、一个功能栏、一个数据栏、一个校验栏和一个结束符。

冒号符(:)作为起始符,回车符(CR)和换行符(LF)是结束符。

ASCII模式允许在两个字符之间有最长1秒的时间间隔。

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

帧起始 地址栏 功能栏 数据栏 校验栏 帧结束 准备就绪
2字符模式
2字符 2字符 N4字符 2字符 回车 换行
16位模式
16 16 N16 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步(继续右移);

   如果移出位为1CRC寄存器异或十六进制数A0001

5、  重复步骤34直到8次右移结束。

6、  异或消息帧的下一个8位数,结果存在CRC寄存器。

7、  重复步骤36直到消息帧的所有数据被处理。

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[i] & 0x00FF;
crc^=c;
for(j=0,j<8,j++)
{ if (crc & 0x0001)
{crc>>=1;crc^=0xA001;}
else crc>>=1
}
}
return(crc);
}

系统分类: 工业控制   |   用户分类: 仪表-软件-通讯   |   来源: 无分类   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(631)    回复(0)  

投一票您将和博主都有获奖机会!