This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP-EXP430FR2355:与对 MSP430中实现的 CRC16-CCITT 的理解相混淆

Guru**** 2575345 points
Other Parts Discussed in Thread: MSP430FR2355

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/965499/msp-exp430fr2355-confused-with-understanding-of-crc16-ccitt-implemented-in-msp430

器件型号:MSP-EXP430FR2355
主题中讨论的其他器件:MSP430FR2355

大家好、团队、

实际上、我正在尝试了解在 msp430FR2355中实现的 CRC16示例代码、我感到困惑。

在线计算出的 CRC16-CCITT 与从 CRC 模块(CRCDIRB)获得的结果不匹配、例如、我发送字符串"BVK"、使 CRC=27860、但在线 CRC16计算器给出的结果为0xE2E7。

我尝试将"BVK"+ CRC 发送到 CRC 模块(CRCDIRB)以获得0结果、但我得到了其他结果。 如果我使用0xE2E7在线 CRC16计算器进行检查、我将按预期获得0。 无法理解问题发生在哪里。  

那么、对于 CRC 模块、如何检查 CRC 正确性? 任何帮助都是非常感谢的。

下面是我已经尝试过的代码 CRC_Str[]="BVK";

#include

unsigned int crc_Init = 0xFFFF;
unsigned int i;
unsigned int crc_Str[]={0x0fc0、0x1096、0x5042、0x0010、// 16个随机16位数
0x7ff7、0xf86a、0xb58e、0x7651、//这些数字可以是
如果需要、可修改0x8b88、0x0679、0x0123、0x9599、//
0xc58c、0xd1e2、0xe144、bbpd691};
unsigned int crc_results;
unsigned int sw_results;
unsigned int crc_new;

//软件算法函数定义
unsigned int CCITT_Update (unsigned int、unsigned int);

int main (空)

WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

P1OUT &=~BIT0;//清除 P1.0输出状态
P1DIR |= BIT0;//将 P1.0设置为输出方向

PM5CTL0 &=~LOCKLPM5;//禁用 GPIO 上电默认高阻抗模式
//激活先前配置的端口设置

//初始化 CRC
CRCINIRES = CRC_Init;//用0xFFFF 初始化 CRC

for (i=0;i<16;i++)

//将随机值输入到 CRC 硬件中
CRCDIRB = CRC_Str[i];//在 CRC 中输入数据
__no_operation();

CRC_Results = CRCINIRES;//保存结果(按照 CRC-CCITT 标准)

CRC_New = CRC_Init;//将 CRC Init 值放入 CRC_New 中
对于(I = 0;I < 16;I++)

//软件算法中的输入值(需要8位输入)
//清除高8位以获得低字节
unsigned int LowByte =(CRC_Str[i]& 0x00FF);
//向右移动8位以获得高位字节
unsigned int UpByte =(CRC_Str[i]>> 8);
//第一个输入低字节
CRC_New = CCITT_Update (CRC_New、LowByte);
//然后输入高字节
CRC_New = CCITT_Update (CRC_New、UpByte);

SW_Results = CRC_New;

//比较数据输出结果
if (crc_results=sw_results)// if data 相等
P1OUT |= BIT0;//设置 LED
其他
P1OUT &=~BIT0;//如果没有、清除 LED

while (1);//无限循环

//软件算法- CCITT CRC16代码
unsigned int CCITT_Update (unsigned int init、unsigned int 输入)

unsigned int CCITT;
CCITT =(unsigned char)(init >> 8)|(init << 8);
CCITT ^=输入;
CCITT ^=(unsigned char)(CCITT & 0xFF)>> 4;
CCITT ^=(CCITT << 8)<< 4;
CCITT ^=((CCITT & 0xFF)<< 4)<< 1;
返回 CCITT;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamshi、

    此示例代码包括软件 CRC 和硬件 CRC。  并比较了这两个计算结果、如果它们相同、则会设置 P1.0。

    您使用的软件 CRC 公式可能与代码中的公式不同。

    谢谢!

    此致

    Johnson

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复、

    但我很清楚这个示例、它在硬件和软件 CRC 之间进行检查。 但我的问题是不同的,让我清楚地解释一下

    我尝试检查 CRC 中是否有字符串"BVK"、但我得到的结果与在线 CRC-CCITT 计算器不匹配。

    2.我尝试将 CRC 结果重新发送到 CRC 模块、我再次得到的值不是零。

    3.如何检查 主器件发送到从器件的5个字节(3字节+ CRC)的接收 CRC。

    4、我假设 XOR CRC 结果、数据产生的 CRC 应为0。 这是错误的假设吗? 那么、如何检查错误呢?

    5.我想使用 CRC8,以便可以使用硬件模块生成 CRC8吗?

    下面是我尝试过的代码。

    #include 
    
    unsigned int crc_Init = 0xFFFF;
    unsigned char crc_Str[]="BVK";
    
    unsigned int i;
    
    unsigned int crc_results、crc_Results1;
    unsigned int sw_results;
    unsigned int crc_new;
    
    //软件算法函数定义
    unsigned int CCITT_Update (unsigned int、unsigned int);
    
    int main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    P1OUT &=~BIT0; //清除 P1.0输出状态
    P1DIR |= BIT0; //将 P1.0设置为输出方向
    
    PM5CTL0 &=~LOCKLPM5;//禁用 GPIO 上电默认高阻抗模式
    //激活先前配置的端口设置
    
    //初始化 CRC
    CRCINIRES = CRC_Init; //用0xFFFF 初始化 CRC
    
    对于(I = 0;I < 3;I++)
    {
    //将随机值输入到 CRC 硬件中
    CRCDIRB = CRC_STR[i]; //在 CRC 中输入数据
    __no_operation();
    }
    CRC_Results1 = CRCINIRES; //保存结果(按照 CRC-CCITT 标准)
    
    CRCINIRES = CRC_Init; //用0xFFFF 初始化 CRC
    对于(I = 0;I < 3;I++)
    {
    //将随机值输入到 CRC 硬件中
    CRCDIRB = CRC_STR[i]; //在 CRC 中输入数据
    __no_operation();
    }
    CRCDIRB = CRC_Results;
    //CRC_Results ^= CRCINIRES;
    CRC_Results = CRCINIRES; //在这里,我应该得到0 ???
    CRC_RESULTS= CRC_RESULTS1 ^;
    
    while (1); //无限循环
    }
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在 GCC 标头中、至少 CRCDIRB 被定义为字寄存器、因此向其写入一个字节会导致问题。 CRCDIRB_L 是我在向 CRC 添加一个数据字节时使用的方法。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 David、  

    这解决了我的问题、但我仍然感到困惑

    *如果我将 CRC 结果发送回 CRC 模块、结果将为0吗?

    以使用 CRC 检查字符串的正确性。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    >       CRCDIRB = CRC_Results;

    您是指什么

    >       CRCDIRB = CRC_Results1;

    也就是说、我不知道这是否会产生0。 我个人只需比较结果。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 Bruce、

    我检查了、它不会生成0。 不知道为什么?

    是否可以使用该 CRC16生成 CRC8?   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    科波曼教授已经写了很多有关 CRC 的内容。 谷歌搜索"CRC Koopman"。