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

UART传输CRC计算:基于LSB原始数据还是MSB传输数据?

CRC计算的字节格式疑问与代码问题

需通过UART传输8字节数据,最后一字节为CRC。已掌握CRC计算方法,但不确定应基于LSB格式的原始数据,还是UART传输时的MSB格式数据进行计算。当前采用紧凑结构体划分1字节数据块,代码如下:

typedef struct __attribute__((packed)){
    uint8_t sync;
    uint8_t slave_address;
    uint8_t register_address;
    uint8_t pwmA;
    uint8_t dirA;
    uint8_t pwmB;
    uint8_t dirB;
    uint8_t crc;
} packet_t;

packet_t new_sig = {
        .sync = 0b10100000,
        .slave_address = 0b10000000,
        .register_address = 0b01000101,
        .pwmA = 0b0,
        .dirA = 0b0,
        .pwmB = 0b0,
        .dirB = 0b0,
        .crc = 0b0,
};

所有数据均为LSB格式,sync、slave_address、register_address为常量,pwmA/B取值0-255,dirA/B为0或1。使用从TMC7300 datasheet获取的CalcCRC函数计算CRC:

void CalcCRC(unsigned char* datagram, unsigned char datagramLength) {
    int i,j;
    unsigned char* crc = datagram + (datagramLength-1); // CRC located in last byte of message
    unsigned char currentByte;
    *crc = 0;
    for (i=0; i<(datagramLength-1); i++) { // Execute for all bytes of a message
        currentByte = datagram[i]; // Retrieve a byte to be sent from Array
        for (j=0; j<8; j++) {
            if ((*crc >> 7) ^ (currentByte&0x01)) // update CRC based result of XOR operation
            {
                *crc = (*crc << 1) ^ 0x07;
            }
            else
            {
                *crc = (*crc << 1);
            }
            currentByte = currentByte >> 1;
        } // for CRC bit
    } // for message byte
    new_sig.crc = *crc;
}

已尝试将数据从LSB转换为MSB进行计算但未解决问题,以下是针对性建议:

  • 优先参考TMC7300手册的CRC示例:直接查手册中的CRC计算样例,用已知的输入数据包和对应正确CRC值做对比测试——这是最快定位问题的方法。比如找手册给出的「输入数据包+正确CRC」组合,用你的代码计算,看结果是否匹配。
  • 修复CalcCRC的冗余赋值:函数最后一行new_sig.crc = *crc;完全多余,因为crc指针已经指向datagram的最后一字节(即new_sig.crc),直接通过*crc赋值即可。保留这行可能导致传入其他datagram时出现错误,建议删除。
  • 校验位处理顺序:当前CalcCRC是按字节的LSB到MSB顺序处理每一位(通过currentByte&0x01取最低位,再右移字节)。如果TMC7300要求按字节MSB到LSB顺序计算CRC,需修改位处理逻辑:
    • 将currentByte&0x01改为(currentByte >> 7) & 0x01(取最高位)
    • 将currentByte = currentByte >> 1改为currentByte = currentByte << 1(左移取次高位)
  • UART传输顺序不影响字节级CRC计算:UART的MSB/LSB传输是字节内部的位顺序,只要收发两端的CRC计算都基于相同的字节数值(即结构体中存储的原始值),就不需要因为UART传输顺序修改CRC计算的字节数据——除非接收端会先反转每个字节的位再计算CRC,这种情况才需要提前反转字节后再算CRC。
  • 确认结构体内存布局:__attribute__((packed))已确保结构体按定义顺序紧凑排列,无字节对齐问题,这部分无需调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:10:55