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

2008-6-5 11:17 3579 9 9 分类: 工业电子

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位模式
1616N1616回车换行


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 & 0x00FF;

crc^=c;

for(j=0,j<8,j++)

{ if (crc & 0x0001)

{crc>>=1;crc^=0xA001;}

else crc>>=1

}

}

return(crc);

}

;i++)>



PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /3 下一条