You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现Modbus ASCII LRC校验生成相关问题咨询

Modbus ASCII从站LRC校验计算说明

1. LRC计算前的格式转换要求

必须先将接收到的ASCII字符转换为对应的十六进制数值,再进行LRC计算。
Modbus ASCII帧中,除开头的冒号:和结尾的CRLF结束符外,所有业务字段(从站地址、功能码、数据域)均采用2个ASCII字符表示1个字节的十六进制值,LRC校验的计算对象是这些原始字节值,而非ASCII字符本身的编码值。

2. ASCII字符转十六进制的实现逻辑

转换规则如下:

  • 09的ASCII字符(编码范围`0x30`0x39):直接减0x30得到对应数值0~9
  • AF的大写ASCII字符(编码范围`0x41`0x46):减0x37得到对应数值10~15
  • af的小写ASCII字符(编码范围`0x61`0x66):减0x57得到对应数值10~15,也可先转大写再按大写规则处理
    注意Modbus ASCII采用2个ASCII字符拼接为1个字节,高4位在前、低4位在后,需要按顺序两两组合转换。

参考实现代码(C语言)

单个ASCII字符转十六进制数值:

uint8_t ascii_to_hex(uint8_t ascii_char) {
    if (ascii_char >= '0' && ascii_char <= '9') {
        return ascii_char - '0';
    } else if (ascii_char >= 'A' && ascii_char <= 'F') {
        return ascii_char - 'A' + 10;
    } else if (ascii_char >= 'a' && ascii_char <= 'f') {
        return ascii_char - 'a' + 10;
    }
    // 非法字符可自行补充错误处理逻辑
    return 0xFF;
}

两个ASCII字符拼接为1个字节:

// ascii_buf为存储主站发送数据的uint8_t数组,跳过索引0的开头冒号
uint8_t high_nibble = ascii_to_hex(ascii_buf[i]);
uint8_t low_nibble = ascii_to_hex(ascii_buf[i+1]);
uint8_t hex_byte = (high_nibble << 4) | low_nibble;

3. 后续LRC校验计算流程

LRC计算规则:将转换得到的所有业务字节(从站地址、功能码、全部数据域字节)依次累加,忽略进位,最终对累加结果取反加1,得到的8位值就是本地计算的LRC校验值,和帧末尾2个ASCII字符转换得到的校验字节对比,一致则校验通过。
LRC计算参考代码:

uint8_t calculate_lrc(uint8_t *hex_data_buf, uint8_t data_len) {
    uint16_t lrc_sum = 0;
    for (uint8_t idx = 0; idx < data_len; idx++) {
        lrc_sum += hex_data_buf[idx];
    }
    lrc_sum = ~lrc_sum + 1;
    return (uint8_t)lrc_sum;
}

内容的提问来源于stack exchange,提问作者Vuko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:15:04