Modbus ASCII模式下的LRC校验算法

在发送报文到平台后重新将数据组织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;
}

你可能感兴趣的:(嵌入式开发)