查看: 3959|回复: 2

[原创] LPC54xx的CRC外设应用

[复制链接]
  • TA的每日心情
    奋斗
    昨天 00:05
  • 签到天数: 1884 天

    连续签到: 9 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112771
    最后登录
    2025-9-12
    发表于 2021-10-9 18:07:57 | 显示全部楼层 |阅读模式
    本帖最后由 stm1024 于 2021-10-10 14:48 编辑

    CRC在通讯中具有广泛的应用,这种算法可以使用软件实现,常见的计算方法有按定义计算,或者使用查表法,前者运算时间较长,后者需要的空间较多,对单片机来说都不是太友好,目前LPC54系列的单片机上已经集成了硬件的CRC Engine,可以说是最省心的方式了。 2.png 1.png 3.png 5.png 4.png 6.png 7.png 8.png 9.png 10.png

    按照官方的用户手册,支持三种CRC计算:
    1.png

    对应的生成多项式分别是0x1021,0x8005和0x04C11DB7。
    在手册后面还提供了对三种CRC算法的使用配置,例如CRC-16 CCITT:
    2.png

    然而我们可以发现,CRC的算法有很多种,参考链接:http://www.ip33.com/crc.html
    万一这三种都不能够满足我们的要求,是否没戏了?只能自己用代码实现?并不是。
    我们稍微深入研究一下CRC的算法,就可以发现,所有的CRC算法,有这么几个选项:
    1. 生成多项式,LPC支持三种生成多项式。
    2. 初始值。
    3. RefIn:待测数据的每个字节是否按位逆序。
    4. RefOut:在计算后之后,异或输出之前,整个数据是否按位逆序。
    5. XOROut:计算结果与此参数异或后得到最终的CRC值。
    如果我们能够配置1-5,那么我们就可以确定一个CRC算法。

    首先最简单的是第二项,初始值,这个可以使用寄存器SEED提供。
    其他四项可以在MODE寄存器中配置,如图:
    3.png

    MODE[1:0]决定了生成多项式,我们只能使用LPC提供的三种生成多项式之一,这个是内部硬件设计决定的,我们不可能跳出这个范围,例如,我们配置使用某个CRC8或者CRC24的算法,这是不可能的了。
    MODE[2]是配置输入的每个字节数据是否要按位逆序,实际上就是RefIn的效果;例如输入数据为0xcd=11001101b的时候,该位如果为1,相当于是输入的数据是10000011b=0x83。
    MODE[3]是配置输入数据是否要按位翻转(取反),这里说明一下,1’s Complement表示按位取反;2’s Complement表示按位取反后再加1。
    MODE[4]是配置校验和(也就是CRC的结果)的整个数据是否要按位逆序,相当于是RefOut。
    MODE[5]是配置校验和的结果是否按位翻转(取反),相当于是XOROut了,如果值是0xff系列,表示结果要按位取反,如果值是0x00系列的,表示不用按位取反。
    再来看看CRC16的算法:
    4.png

    可以发现,9种算法中,除了最后的CRC-16/DNP因为生成多项式不同无法计算外, 其他的都可以通过配置MODE寄存器和提供SEED实现。其中上面四个使用的生成多项式是0x8005,下面四种使用的是0x1021,这都是LPC54系列可以支持的,我们可以通过如下代码实现算法的配置:宏定义:
    1.           //初始值        结果异或值        输入反转        输出反转
    2. //poly 0x1021
    3. #define CRC16_CCITT                        0//0000                0000                T                        T
    4. #define CRC16_CCITT_FALSE        1//FFFF                0000                F                        F
    5. #define CRC16_X25                        2//FFFF                FFFF                T                        T
    6. #define        CRC16_XMODEM                3//0000                0000                F                        F

    7. //Poly 0x8005
    8. #define CRC16_IBM                        4//0000                0000                T                        T
    9. #define CRC16_MAXIM                        5//0000                FFFF                T                        T
    10. #define CRC16_USB                        6//FFFF                FFFF                T                        T
    11. #define CRC16_MODBUS                7//FFFF                0000                T                        T

    12. //ploy 04C11DB7
    13. #define CRC32                                8//FFFFFFFF        FFFFFFFF        T                        T
    14. #define CRC32_MPEG2                        9//FFFFFFFF        00000000        F                        F


    15. #define CRC16_1021_MODE                0x00
    16. #define CRC16_8005_MODE                0x01
    17. #define CRC32_MODE                        0x02

    18. #define CRC_REFIN                        (1U<<2)
    19. #define CRC_REFOUT                        (1U<<4)
    20. #define CRC_XOROUT                        (1U<<5)
    复制代码

    算法配置代码(顺带把CRC32也一并写进去),一共是10种CRC算法:
    1. void XDCRC_SetAlgorithm(uint8_t type)
    2. {
    3.         XDCRC_Reset();
    4.         switch(type)
    5.         {
    6.                 case CRC16_CCITT:
    7.                         CRC_ENGINE->MODE=CRC16_1021_MODE|CRC_REFIN|CRC_REFOUT;
    8.                         CRC_ENGINE->SEED=0x0000;
    9.                         break;
    10.                 case CRC16_CCITT_FALSE:
    11.                         CRC_ENGINE->MODE=CRC16_1021_MODE;
    12.                         CRC_ENGINE->SEED=0xffff;
    13.                         break;

    14.                 case CRC16_X25:
    15.                         CRC_ENGINE->MODE=CRC16_1021_MODE|CRC_REFIN|CRC_REFOUT|CRC_XOROUT;
    16.                         CRC_ENGINE->SEED=0xffff;
    17.                         break;
    18.                
    19.                 case CRC16_XMODEM:
    20.                         CRC_ENGINE->MODE=CRC16_1021_MODE;
    21.                         CRC_ENGINE->SEED=0x0000;
    22.                         break;
    23.                
    24.                 case CRC16_IBM:
    25.                         CRC_ENGINE->MODE=CRC16_8005_MODE|CRC_REFIN|CRC_REFOUT;
    26.                         CRC_ENGINE->SEED=0x0000;
    27.                         break;
    28.                
    29.                 case CRC16_MAXIM:
    30.                         CRC_ENGINE->MODE=CRC16_8005_MODE|CRC_REFIN|CRC_REFOUT|CRC_XOROUT;
    31.                         CRC_ENGINE->SEED=0x0000;
    32.                         break;
    33.                
    34.                 case CRC16_USB:
    35.                         CRC_ENGINE->MODE=CRC16_8005_MODE|CRC_REFIN|CRC_REFOUT|CRC_XOROUT;
    36.                         CRC_ENGINE->SEED=0xffff;
    37.                         break;
    38.                
    39.                 case CRC16_MODBUS:
    40.                         CRC_ENGINE->MODE=CRC16_8005_MODE|CRC_REFIN|CRC_REFOUT;
    41.                         CRC_ENGINE->SEED=0xffff;
    42.                         break;
    43.                
    44.                 case CRC32:
    45.                         CRC_ENGINE->MODE=CRC32_MODE|CRC_REFIN|CRC_REFOUT|CRC_XOROUT;
    46.                         CRC_ENGINE->SEED=0xffffffff;
    47.                         break;
    48.                 case CRC32_MPEG2:
    49.                         CRC_ENGINE->MODE=CRC32_MODE;
    50.                         CRC_ENGINE->SEED=0xffffffff;
    51.                         break;
    52.         }
    53. }
    复制代码
    另外,在使用的时候,一定要注意,完成一次校验和计算以后,要记得将该外设复位,否则之前的计算结果会影响到第二次的计算。
    测试效果:
    5.png





    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2025-8-8 16:43
  • 签到天数: 1504 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    97

    主题

    4693

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10105
    最后登录
    2025-9-11
    发表于 2021-10-9 19:20:09 | 显示全部楼层
    这个东西高级了呀
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-8-8 16:43
  • 签到天数: 1504 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    97

    主题

    4693

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10105
    最后登录
    2025-9-11
    发表于 2021-10-9 19:21:15 | 显示全部楼层
    原来其它的多项式可以通过参数设置。
    平时一直使用CRC16-Modbus
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-13 08:22 , Processed in 0.096376 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表