打印

快速CRC16-CCITT算法,速度与查表法相当

[复制链接]
7942|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ZALIN|  楼主 | 2011-6-1 01:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是针对IAR EWAVR的内联汇编优化代码,包含C代码。
如果使用C的话,需要针对使用的MCU和编译器作些优化。

//
// for iar ewavr
//
//----------------------------------------------------------------------------------------------
//
// CRC16-CCITT(ITU), 多项式: x16+x12+x5+1, LSB右移(0x8408).
//
unsigned short crc16_itu_lsb( unsigned short crc, unsigned int len, unsigned char *data )
{
//    unsigned char temp;
//    while(len--)
//    {
//        temp = crc ^ *data++;
//        temp ^= temp<<4;
//        crc = (crc>>8) ^ (temp<<3) ^ (temp<<8) ^ (temp>>4);
//    }
//    return crc;
    __asm ( "   MOVW    R30, R20            \n" // R21:R20 = unsigned char *data
            "   LDI     R20, 1<<4           \n"
            "   RJMP    crc16_itu_lsb_while \n"
            "crc16_itu_lsb_do:              \n"
//        temp = crc ^ *data++;
            "   LD      R0, Z+              \n"
            "   EOR     R16, R0             \n" // R16 = crc^*data
//        temp ^= temp<<4;
            "   MUL     R16, R20            \n" // R0  = temp<<4
            "   EOR     R16, R0             \n" // R16 = temp^(temp<<4)
//        crc = (crc>>8) ^ (temp<<3) ^ (temp<<8) ^ (temp>>4);
            "   MUL     R16, R20            \n" // R1:R0 = temp<<4
            "   EOR     R17, R1             \n" // R17 = (crc>>8)^(temp>>4)
            "   LSR     R1                  \n"
            "   ROR     R0                  \n" // R1:R0 = temp<<3
            "   EOR     R0, R17             \n" // R0  = crc_l
            "   EOR     R1, R16             \n" // R1  = crc_h
            "   MOVW    R16, R0             \n" // R17:R16 = unsigned short crc
            "crc16_itu_lsb_while:           \n"
            "   SUBI    R18, 1              \n" // R19:R18 = unsigned int len
            "   SBCI    R19, 0              \n"
            "   BRCC    crc16_itu_lsb_do    \n"
        );
    return crc;
}
//----------------------------------------------------------------------------------------------
//
// CRC16-CCITT(ITU), 多项式: x16+x12+x5+1, MSB左移(0x1021).
//
unsigned short crc16_itu_msb( unsigned short crc, unsigned int len, unsigned char *data )
{
//    unsigned char temp;
//    while(len--)
//    {
//        temp = (crc>>8) ^ *data++;
//        temp ^= temp>>4;
//        crc = (crc<<8) ^ (temp<<5) ^ (temp<<0) ^ (temp<<12);
//    }
//    return crc;
    __asm ( "   MOVW    R30, R20            \n" // R21:R20 = unsigned char *data
            "   LDI     R20, 1<<4           \n"
            "   RJMP    crc16_itu_msb_while \n"
            "crc16_itu_msb_do:              \n"
//        temp = (crc>>8) ^ *data++;
            "   LD      R0, Z+              \n"
            "   EOR     R17, R0             \n" // R17 = (crc>>8)^*data
//        temp ^= temp>>4;
            "   MUL     R17, R20            \n" // R1  = temp>>4
            "   EOR     R17, R1             \n" // R17 = temp^(temp>>4)
//        crc = (crc<<8) ^ (temp<<5) ^ (temp<<0) ^ (temp<<12);
            "   MUL     R17, R20            \n" // R1:R0 = temp<<4
            "   EOR     R16, R0             \n" // R16 = (crc<<8)^(temp<<12)
            "   LSL     R0                  \n"
            "   ROL     R1                  \n" // R1:R0 = temp<<5
            "   EOR     R0, R17             \n" // R0  = crc_l
            "   EOR     R1, R16             \n" // R1  = crc_h
            "   MOVW    R16, R0             \n" // R17:R16 = unsigned short crc
            "crc16_itu_msb_while:           \n"
            "   SUBI    R18, 1              \n" // R19:R18 = unsigned int len
            "   SBCI    R19, 0              \n"
            "   BRCC    crc16_itu_msb_do    \n"
        );
    return crc;
}

相关帖子

沙发
hotpower| | 2011-6-13 07:34 | 只看该作者
板凳
mcuisp| | 2011-6-13 10:47 | 只看该作者
好东西,谢谢分享

使用特权

评论回复
地板
ayl439| | 2011-12-14 21:14 | 只看该作者
谢谢分享!

使用特权

评论回复
5
dengm| | 2011-12-15 16:35 | 只看该作者
查表法可快10倍

使用特权

评论回复
6
lxyppc| | 2011-12-15 20:10 | 只看该作者
可以看看wiki上的非查表crc并行算法

使用特权

评论回复
7
dengm| | 2011-12-16 09:46 | 只看该作者
本帖最后由 dengm 于 2011-12-16 09:48 编辑

8位MCU, 查一个表(512bytes) 2 次
16位MCU, 查二个表(2*512bytes)

使用特权

评论回复
8
hotpower| | 2018-12-30 01:05 | 只看该作者

使用特权

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

本版积分规则

1

主题

48

帖子

2

粉丝