打印
[创客交流]

【Navota开发板】第二篇: CRC程序小试

[复制链接]
1647|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Harvard|  楼主 | 2016-11-30 00:07 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Harvard 于 2016-11-30 00:08 编辑

  首先,什么是CRC?

循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或电脑文件等数据产生简短固定位数校验码的一种散列函数,主要用来检测或校验数据传输或者保存后可能

出现的错误。它是利用除法及余数的原理来作错误侦测的。

CRC在串口通信中很常见,如常见的ModbusRtu 采用的就是CRC16, 不同的CRC有不同的多项式;如果用纯软件代码来实现CRC,流程都非常类似; 可以看一个例子:

生成  CRC  的过程为:
1. 将一个  16 位寄存器(称作  CRC 寄存器)初始赋值为十六进制  FFFF (全 1);
2. 将报文的第一个字节( 8位)与 16 位 CRC 寄存器的低字节异或,结果置于 CRC 寄存器;
3. 将  CRC 寄存器右移 1位  (向  LSB 方向), MSB 充零,并检测  LSB
4. (如果 LSB 为  0): 重复步骤  3 (另一次移位).
  (如果 LSB 为 1): 对 CRC 寄存器异或多项式值  0xA001 (1010 0000 0000 0001).
5. 重复步骤  3 和 4,直到完成  8 次移位操作后,一个字节的处理完毕。
6. 对报文中的下一个字节重复步骤 2 到 5继续此操作,直至所有报文被处理完毕。
7. CRC 寄存器中的最终值为 CRC 值.
8. 当放置 CRC 值于报文时,注意高低字节必须交换。


看了以上过程是不是 感觉繁琐, 大概理解,但是毕竟还是需要代码去完成, 随着技术发展,如今的很多单片机,把crc模块变成了标准内部资源,Navota100系列也是如此.

循环冗余校验(CRC)模块生成16/32 位CRC 码以便进行误差检测,CRC 模块提供实施16 位或32 位CRC标准所需的可编程多项式、WAS 和其他参数。对于32 位数据,每次都计算该16/32 位代码。
注:MCU 进去低功耗模式后,该模块时钟禁用,任何进行中的CRC 计算都会停止。
具体crc的性能,可以看数据手册. 我本次实验的目地就是看crc模块,是否可以工作.因此,编译并运行了厂家开发包中的nv32f100_pdk\build\keil\NV32\CRC_demo例程,虽为crc体验,其实同时也学习了UART,实验是从串口1输出了一些信息.利用的是printf函数功能,同时,系统配置的是115200bps的波特率,大家注意.开发板自带的ft232驱动也记得装好. 串口调试软件打开时,选择正确的波特率和串口号.




<span style="font: 14px/24px arial, 宋体, sans-serif; color: rgb(51, 51, 51); text-transform: none; text-indent: 28px; letter-spacing: normal; word-spacing: 0px; float: none; display: inline !important; white-space: normal; widows: 1; font-size-adjust: none; font-stretch: normal; background-color: rgb(255, 255, 255); -webkit-text-stroke-width: 0px;"></span>


<p><span style="font: 14px/24px arial, 宋体, sans-serif; color: rgb(51, 51, 51); text-transform: none; text-indent: 28px; letter-spacing: normal; word-spacing: 0px; float: none; display: inline !important; white-space: normal; widows: 1; font-size-adjust: none; font-stretch: normal; background-color: rgb(255, 255, 255); -webkit-text-stroke-width: 0px;">/********************************************************************/
int main (void)
{   
    uint8_t         u8Ch;
    uint32_t        u32Crc_ConverterResult;
    uint32_t        u32SeedValue;  
    CRC_ConfigType  sCRC_ConfigType = {0};
    CRC_ConfigType  *pCRC_Config=&sCRC_ConfigType;</span></p><p><span style="font: 14px/24px arial, 宋体, sans-serif; color: rgb(51, 51, 51); text-transform: none; text-indent: 28px; letter-spacing: normal; word-spacing: 0px; float: none; display: inline !important; white-space: normal; widows: 1; font-size-adjust: none; font-stretch: normal; background-color: rgb(255, 255, 255); -webkit-text-stroke-width: 0px;">    uint8_t MessageSource[] = {"123456789"} ;                      /*!< initialize mesasge */  </span></p><p><span style="font: 14px/24px arial, 宋体, sans-serif; color: rgb(51, 51, 51); text-transform: none; text-indent: 28px; letter-spacing: normal; word-spacing: 0px; float: none; display: inline !important; white-space: normal; widows: 1; font-size-adjust: none; font-stretch: normal; background-color: rgb(255, 255, 255); -webkit-text-stroke-width: 0px;">    /* Perform processor initialization */
    sysinit();</span></p><p><span style="font: 14px/24px arial, 宋体, sans-serif; color: rgb(51, 51, 51); text-transform: none; text-indent: 28px; letter-spacing: normal; word-spacing: 0px; float: none; display: inline !important; white-space: normal; widows: 1; font-size-adjust: none; font-stretch: normal; background-color: rgb(255, 255, 255); -webkit-text-stroke-width: 0px;">    printf("\nRunning the CRC_demo project.\n");         
    /* inital CRC register works under 16-bit mode */
    pCRC_Config->u32PolyData            = 0x1021;                   /*!< initialize CRC-CCITT poly value */
    u32SeedValue                        = 0xFFFF;                   /*!< set CRC-CCITT seed value */     
    pCRC_Config->bWidth                 = CRC_WIDTH_16BIT;
    pCRC_Config->bTransposeReadType     = CRC_READ_TRANSPOSE_NONE;  /*!< do not transpose in read */      
    pCRC_Config->bTransposeWriteType    = CRC_WRITE_TRANSPOSE_NONE; /*!< do not transpose in write */
    /* begin to CRC-CCITT convertion */   
    CRC_Init(pCRC_Config);                                          /*!< crc module inital as 16-bit mode */  
   
    printf("CRC0->GPOLY=0x%x, CRC0->CTRL=0x%x\n",CRC0->GPOLY,CRC0->CTRL);
   
    u32Crc_ConverterResult = CRC_Cal16(u32SeedValue, &MessageSource[0], (sizeof(MessageSource)-1));   
    printf("CRC-CCITT function calculation result = 0x%x [url=home.php?mod=space&uid=14343]@seed[/url] = 0x%x .\n", u32Crc_ConverterResult, u32SeedValue );
   
    /* reset CRC register for 32-bit mode calculation*/
    CRC_DeInit();  
   
    /* inital CRC register works under 32-bit mode */
    pCRC_Config->u32PolyData            = 0x04C11DB7;               /*!< set CRC32 poly value */      
    u32SeedValue                        = 0xFFFFFFFF;               /*!< set CRC32 seed value */  
    pCRC_Config->bWidth                 = CRC_WIDTH_32BIT;
    pCRC_Config->bTransposeReadType     = CRC_READ_TRANSPOSE_ALL;   /*!< do not transpose in read */      
    pCRC_Config->bTransposeWriteType    = CRC_WRITE_TRANSPOSE_BIT;  /*!< do not transpose in write */
    pCRC_Config->bFinalXOR              = TRUE;                     /*!< reverse CRC result */
    /* begin to CRC-CCITT convertion */   
    CRC_Init(pCRC_Config);                                          /*!< crc module inital as 32-bit mode */      
    u32Crc_ConverterResult = CRC_Cal32(u32SeedValue, &MessageSource[0], (sizeof(MessageSource)-1));   
    printf("CRC32 function calculation result = 0x%x [url=home.php?mod=space&uid=14343]@seed[/url] = 0x%x .\n", u32Crc_ConverterResult, u32SeedValue );</span></p><p><span style="font: 14px/24px arial, 宋体, sans-serif; color: rgb(51, 51, 51); text-transform: none; text-indent: 28px; letter-spacing: normal; word-spacing: 0px; float: none; display: inline !important; white-space: normal; widows: 1; font-size-adjust: none; font-stretch: normal; background-color: rgb(255, 255, 255); -webkit-text-stroke-width: 0px;">   
    while(1)
    {  
        u8Ch = UART_GetChar(TERM_PORT);  
        UART_PutChar(TERM_PORT, u8Ch);
    }
}</span></p>




相关帖子

沙发
Harvard|  楼主 | 2016-11-30 00:09 | 只看该作者
--System Log BEGINS--


Familly ID = 0x0, Sub-family ID = 0x2, Revision ID = 0x0, Pin ID = 0x7
SWD Reset

--System Log ENDS--


Running the CRC_demo project.
CRC0->GPOLY=0x1021, CRC0->CTRL=0x0
CRC-CCITT function calculation result = 0x29b1 @seed = 0xffff .
CRC32 function calculation result = 0xcbf43926 @seed = 0xffffffff .
0
1
3
以上为运行结果. 0 -1 3 为while循环实现的串口回显功能. 发什么过去 串口就给我们返回相应的字符.

使用特权

评论回复
板凳
上官梦舞| | 2016-11-30 11:18 | 只看该作者
谢谢分享,方便校验数据。

使用特权

评论回复
地板
上官梦舞| | 2016-11-30 11:20 | 只看该作者
之前一直没有用过CRC虽然知道是做数据校验的。

使用特权

评论回复
5
Harvard|  楼主 | 2016-11-30 16:41 | 只看该作者
哈哈 都可以固化成一个函数或者模块了 不用掌握了.

使用特权

评论回复
6
Harvard|  楼主 | 2016-11-30 16:43 | 只看该作者
 u16  _crc16_update0(u16 crc, u08 a)
{
        int i;
        crc ^= a;
        for (i = 0; i < 8; ++i)
        {
            if (crc & 1)
                crc = (crc >> 1) ^ 0xA001;
            else
                crc = (crc >> 1);
        }
        return crc;
}
现在的arm跑的很快 有时候为了移植性 我都不用crc模块 直接计算.

使用特权

评论回复
7
hotpower| | 2016-12-20 15:49 | 只看该作者
http://www.21ic.com/tools/HotWC3_V1.22.html

使用特权

评论回复
8
Harvard|  楼主 | 2016-12-20 21:57 | 只看该作者
哈哈 谢谢菜农 捧场 .你的crc 天下无敌.

使用特权

评论回复
9
上官梦舞| | 2016-12-21 08:30 | 只看该作者
Harvard 发表于 2016-12-20 21:57
哈哈 谢谢菜农 捧场 .你的crc 天下无敌.

他的CRC看的头晕目眩!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:单片机工作者

74

主题

1729

帖子

21

粉丝