在发送报文到平台后重新将数据组织LRC校验码,但是使用Modbus规约文档上给的代码总是与发送报文的校验码不符, 查资料可知LRC校验码的算法有两种,实现起来也很简单.但是却不对.因为这些都是一个字节的, 但是发送报文中其实是两个字节的校验码,其高位在后,低位在前! 这与前面几段数据不同,需要注意下.没办法, 网上的资料虽多,但是能用的也寥寥. 不过有两份资料还是说明出问题的要害, LRC校验C代码 和 LRC校验的可能的正确理解. 遂按照第一份资料的代码编写了一段,然后调试可用. 代码如下:
VOID make_lrc_2char(UINT8* pBuf,INT32 iDataLen,UCHAR *pucLrcH,HT_UCHAR *pucLrcL)
{
UINT8 *pushMsg = pBuf + 1,pushBuf[MAX_BUF_LENGTH];//+1是因为报文头的0x3A是不参加LRC校验的
UCHAR ucIndex_Temp =0, ucIndex = 0;
UINT8 ucLrcH = 0xff;
UINT8 ucLrcL = 0xff;
INT32 i ;
UINT LrcCheck = 0;
for( i = 0;i < iDataLen ; i++)
{
if(pushMsg[i] >= 0x41)//'A'....
{
pushBuf[i] =pushMsg[i] -0x41 + 10;
}else{//'0...'
pushBuf[i] = pushMsg[i] - 0x30;
}
ucIndex_Temp += pushBuf[i];
}
ucIndex =(HT_UCHAR) ((~ucIndex_Temp) + 1);
LrcCheck = AsciitoHex(ucIndex);
*pucLrcH = (LrcCheck&0xFF00)>>8;
*pucLrcL = LrcCheck&0xFF;
}
UINT AsciitoHex(UCHAR iFrame)
{
UINT iDecT = 0;
//hex>>ascii
UCHAR iFrameH = (iFrame>>4)&0xF;
UCHAR iFrameL = iFrame&0xF;
if(iFrameH > 9) iFrameH = iFrameH -10 +65;
else iFrameH = iFrameH + 48;
if(iFrameL > 9) iFrameL = iFrameL -10 + 65;
else iFrameL = iFrameL +48;
iDecT = (iFrameH << 8)|iFrameL;
return iDecT;
}