一起学CC3200之CRC校验

一起学CC3200之

CRC校验

小阿汤哥

序:

能力有限,难免有错,有问题请联系我,请留言或者邮件联系

QQ群交流:482729453   邮件联系hytga@163.com 

资料共享链接http://pan.baidu.com/s/1hqiWB56

版本:20160323

 

 

一起学CC3200之    - 1 -

CRC校验    - 1 -

一、    CRC简介    - 1 -

二、    CC3200的CRC    - 3 -

三、    软件说明    - 3 -

四、    API函数    - 9 -

五、    测试及示例代码    - 10 -

六、    总结    - 18 -

 

 

 

 

 

 

 

 

  1. CRC简介

    百度百科:CRC循环冗余校验码Cyclic Redundancy Check[1]  ):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。

     

     

    那么什么是CRC?简单地说就是一个用来判断数据有没有错,譬如:数据:"432432"的检验码为90,你把"432432"和90发给其他设备,其他设备对"432432"进行计算,如果得到的值不是90,那么这串数据就是有问题的。有问题的数据肯定是直接扔掉的。

     

    CRC有一个比较重要的东西叫做多项式:多项式为x5+x3+x2+x+1对应的代码101111

    这个具体是做啥的?自己百度下。

    我有两个软件请看:两个字符串计算出来的是一样的。

    CRC的多项式有很多种:

     

  2. CC3200内部具有硬件的CRC校验功能。

    目前找不到有关CRC模块的介绍,只能从官方例程找到怎么用这个CRC,可能是官方觉得这个太简单了,没必要写了吧。

    但是我告诉你CRC其实是有bug的。为什么说是有bug,请继续看。当然如果对于懂的人来说可能不是bug。对于不懂的人来说,想了老半天,不知道是啥意思?毕竟没有中文文档,除非你去问官方。

     

    CC3200只支持一部分的多项式:5种

    够用了,如果不支持的,可以去找一些代码(肯定是有人奉献出来了),或者自己编写。

  3. 先说说这两个工具

    上面两图的信息是有点不太一样的,我是没研究CRC,反正这东西拿过就是验证下对不对,然后下了两个软件,结果发现有点不太一样,不同人写的,估计就是不太一样的,那么怎么把两个软件一一对应起来?为什么要对应起来?只因为我不知道哪个是正确的。

    请看下图,红色连起来就是有直接关系的。

     

    Ploy

    多项式

    Init

    初始值

    Refin==false refou==false

    数据反转:MSB first

    Refin==True refou==true

    数据反转:LSB first

    Xorout

    异或值

    请注意上面是根据经验得到的,他们为什么这样我并不知道。没去研究CRC算法。

    下面有这两个的测试示例:

    测试1:

    测试2:

    测试3:

    测试4:

    测试5:

     

     

  4. //配置CRC

    1. extern void CRCConfigSet(uint32_t ui32Base, uint32_t ui32CRCConfig);

    //数据处理

    1. extern uint32_t CRCDataProcess(uint32_t ui32Base, void *puiDataIn,

    uint32_t ui32DataLength, uint32_t ui32Config);

    //写数据

    1. extern void CRCDataWrite(uint32_t ui32Base, uint32_t ui32Data);

    //读结果

    1. extern uint32_t CRCResultRead(uint32_t ui32Base);

    //设置种子

    1. extern void CRCSeedSet(uint32_t ui32Base, uint32_t ui32Seed);

    这上面序号为 1 , 2 ,5 比较常用,另外两个没啥作用,CRCDataProcess这个函数就是包含了CRCDataWrite和CRCResultRead这两个功能。

  5. CRC很简单:

    1. 使能时钟。
    2. 配置。
    3. 输入数据返回结果。

     

    简单吧!

    示例:

    多项式为:

    数据宽度为:8bit

    种子为:0

    什么是种子?假设你要上传10000T的数据到网盘,怎么办?只能注册10000个账号,一个账号传1T,哈哈,撑死百度。

    这种子也是这个作用,你检验1000个数据,分批校验,第一次检验100,得到结果假设为90,那么90就作为种子,进行下一次的校验。就这样一直循环,直到校验完成。

    什么是数据宽度?数据宽度就是你输入的数据的最小宽度是8bit 或者是32bit。

     

    示例:代码将放在后面

    测试1

    测试2

    这个就是bug所在,这个需要对调字节。

     

     

    测试3.

     

     

    测试 4

    测试 5

     

    测试 6

     

     

    代码

    MAP_PRCMPeripheralClkEnable(PRCM_DTHE, PRCM_RUN_MODE_CLK);

    unsigned long retVal;

    //配置 1

    MAP_CRCConfigSet(CCM0_BASE, CRC_CFG_TYPE_P8005 | CRC_CFG_SIZE_8BIT);

    //种子

    MAP_CRCSeedSet(CCM0_BASE, 0);

    //数据输入,得到结果

    retVal= MAP_CRCDataProcess(CCM0_BASE, (void*) "11111111111111",

    sizeof("11111111111111") - 1, CRC_CFG_SIZE_8BIT);

    UART_PRINT("标志 :CRC_CFG_TYPE_P8005 | CRC_CFG_SIZE_8BIT ");

    UART_PRINT("初始值:0 ");

    UART_PRINT("数据 :11111111111111 ");

    UART_PRINT("校验码: %x ", retVal);

     

     

     

    //配置 2

    MAP_CRCConfigSet(CCM0_BASE, CRC_CFG_TYPE_P8005 | CRC_CFG_SIZE_8BIT|CRC_CFG_OBR|CRC_CFG_IBR);

    //种子

    MAP_CRCSeedSet(CCM0_BASE, 0);

    //数据输入,得到结果

    retVal= MAP_CRCDataProcess(CCM0_BASE, (void*) "11111111111111",

    sizeof("11111111111111") - 1, CRC_CFG_SIZE_8BIT);

    UART_PRINT("标志 : CRC_CFG_TYPE_P8005 | CRC_CFG_SIZE_8BIT|CRC_CFG_OBR|CRC_CFG_IBR ");

    UART_PRINT("初始值:0 ");

    UART_PRINT("数据 :11111111111111 ");

    UART_PRINT("校验码: %x ", retVal);

     

     

    //配置 3

    MAP_CRCConfigSet(CCM0_BASE, CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT|CRC_CFG_OBR|CRC_CFG_IBR);

    //种子

    MAP_CRCSeedSet(CCM0_BASE, 0);

    //数据输入,得到结果

    retVal= MAP_CRCDataProcess(CCM0_BASE, (void*) "12345678",

    2, CRC_CFG_SIZE_32BIT);

    UART_PRINT("标志 : CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT|CRC_CFG_OBR|CRC_CFG_IBR ");

    UART_PRINT("初始值:0 ");

    UART_PRINT("数据 :12345678 ");

    UART_PRINT("校验码: %x ", retVal);

     

    //配置 4

    MAP_CRCConfigSet(CCM0_BASE, CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT);

    //种子

    MAP_CRCSeedSet(CCM0_BASE, 0);

    //数据输入,得到结果

    retVal= MAP_CRCDataProcess(CCM0_BASE, (void*) "12345678",

    2, CRC_CFG_SIZE_32BIT);

    UART_PRINT("标志 : CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT ");

    UART_PRINT("初始值:0 ");

    UART_PRINT("数据 :12345678 ");

    UART_PRINT("校验码: %x ", retVal);

     

    //配置 5

    MAP_CRCConfigSet(CCM0_BASE, CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT);

    //种子

    MAP_CRCSeedSet(CCM0_BASE, 0x222);

    //数据输入,得到结果

    retVal= MAP_CRCDataProcess(CCM0_BASE, (void*) "12345678",

    2, CRC_CFG_SIZE_32BIT);

    UART_PRINT("标志 : CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT ");

    UART_PRINT("初始值:0x222 ");

    UART_PRINT("数据 :12345678 ");

    UART_PRINT("校验码: %x ", retVal);

     

     

     

    //配置 6

    MAP_CRCConfigSet(CCM0_BASE, CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT|CRC_CFG_RESINV);

    //种子

    MAP_CRCSeedSet(CCM0_BASE, 0x222);

    //数据输入,得到结果

    retVal= MAP_CRCDataProcess(CCM0_BASE, (void*) "12345678",

    2, CRC_CFG_SIZE_32BIT);

    UART_PRINT("标志 : CRC_CFG_TYPE_P4C11DB7 | CRC_CFG_SIZE_32BIT|CRC_CFG_RESINV ");

    UART_PRINT("初始值:0x222 ");

    UART_PRINT("数据 :12345678 ");

    UART_PRINT("校验码: %x ", retVal);

     

     

  6. CC3200的CRC有bug,或者是我少设置了其他东西,具体看第五部分测试及示例代码。

原文地址:https://www.cnblogs.com/hytgab/p/5313419.html