原创 使用半字节查表法之CRC16的code sample(一)

2010-8-6 08:26 5236 18 24 分类: 消费电子

在进行通讯的过程中, 我们需要和CRC打交道. Allen觉得, 尽管在很多时候, CRC并不是那么重要. 但是出于通讯协议兼容, 我们往往被迫使用CRC计算. 在通宵的工作过程中, Allen 对网络资源进行了一番整理, 并自行加入理解, 便于同行们, 在相应工作时, 节省大量查阅资料的时间.

前提:
1. 运算法则的可靠性: 在反复检索资料后, Allen 意识到, 弄清运算法则需要至少1个工作日, 用大量实例和思考, 并配合相当的实例进行思考. 在极大的项目时间压力下, 我们放弃这个know-why 的行为. 我们接受现有算法, 作为"定理"的引用, 而非作为一个严谨算数逻辑推导的结果.


CRC要素:
1. 多项式除法
在进行 CRC 计算之前, 我们不得不重温多项式除法. 检索:  http://certmaths.ilongman.com/chi/ppt/ch03/lecture03_02c.ppt 的 ppt 文档.
大致我们知道: 多项式除以单项式时, 我们可以使用分配率. 而多项式除以多项式时, 我们必须使用长除法.

2. CRC原理
简单描述: 把待传送的数据 M 的二进制码序列看成多项式 M, 事先选定一个 r+1 bit 的二进制数看成多项式 P, 把多项式 M 除以 P, 得到商Q 和余数 R(r bit), 把余数 R 附加在信息码 M 一起发送. 在接收端, 使用同样的 M/P 获取余数 R', 与 R 比较验证 M 是否正确.
引用讨论: http://topic.csdn.net/u/20090625/09/d3121402-443c-4d6d-be2d-6746f9434c72.html

举例说明:
信息位: 1011001
CRC码: 4位 r = 4
校验多项式(生成码): 11001 (x4+x3+1)
运算步骤: 1011001 -> 左移4位 -> 10110010000 -> 除以 11001 -> 遵守运算法则: 不借位除法, 即异或运算, 得到结果(余数) 1010, 即为 CRC 码.

3. 例程实现:
CRC的算法包括: 基本算法, 字节查表法, 半字节查表法
我们主要讨论 16 bit 的 CRC 实现, 使用 CRC16-CCITT, 也即是 X16+X12+X5+1, 生成码为 0x1021. 本来实际值应该是 0x010121, 这里又引入了一个运算法则: "最高位一定为1故抛弃", 因此是 0x1021.

3.1 基本算法:
http://read.pudn.com/downloads90/sourcecode/embed/341559/crc.c__.htm


/**************************************************************** 
 *函数性质:公共 
 *入口:要进行CRC校验的数据缓冲unsigned char *ptr,要进行CRC校验的数据长度 
 *出口:CRC计算结果 
 *功能:CRC16计算(计算速度慢,程序空间小) 
 *调用方式:unsigned short CalCRC16Slow(unsigned char *ptr, unsigned char len) 
*****************************************************************/  
#if CRC16 == CRC16SLOW   
unsigned short CalCRC16Slow(unsigned char *ptr, unsigned char len)  
{  
    unsigned char i;  
    unsigned short crc = 0;  
    while(len--!=0)   
    {  
        for(i = 0x80; i != 0; i/=2)   
        {  
            if((crc&0x8000)!=0)   
            {  
                crc*=2;   
                crc^=0x1021;  
            }                                           /* 余式CRC乘以2再求CRC  */  
            else crc*=2;  
            if((*ptr&i)!=0) crc^=0x1021;                /* 再加上本位的CRC */  
        }  
        ptr++;  
    }  
    return(crc);  
}  
#endif   
注: 我们未验证该例程. 并注意到这里又引入了一个运算法则: 使用模2的方式, 进行异或运算(应该指不借位除法).

使用半字节查表法之CRC16的code sample(一)
使用半字节查表法之CRC16的code sample(二)

 

文章评论6条评论)

登录后参与讨论

用户1249549 2011-6-9 11:50

hao

allen_zhan_752827529 2010-8-16 07:54

Windy` Sorry` It is urgent for our current case. If you dig what the rule means, pls teach me.

用户1210019 2010-8-15 20:11

能不能详细说明一下“生成码为 0x1021. 本来实际值应该是 0x010121”的来历?谢谢!

用户1011588 2010-8-9 13:38

能共享很不错!

用户1409907 2010-8-9 10:15

辛苦了, 通过楼主的说明, 我对这个多项式也基本了解了。

用户1277994 2010-8-6 16:39

多谢博主allen,辛苦了。
相关推荐阅读
allen_zhan 2023-02-27 19:08
对"三极管"译名由来的探讨
想讨论一个有意思的话题:今天中国大陆的电子业界, 为何将 BJT 称呼为 "三极管"? 或因其象形, 前辈自行进行随意的不严谨定义么? 带着疑问我们做了一下延伸查阅, 或得出这样的结论, 即中译名"三...
allen_zhan 2023-02-19 18:15
对知乎提问"为何三极管的一个PN结工作在反偏"的回复
将这个回复, 也发表在博文中, 作为自己的一个学习笔记叭.知乎问题: "三极管里面的PN结相当于二极管,为什么里面PN结加反向电压也能导通?"我的回复:首先, 二极管的"反向"概念, 容易给初学者某种...
allen_zhan 2023-02-18 10:17
从肖特基二极管到PN结与三极管
最近数个工作日的兴趣是回顾电子基础器件的发明/发展历史, 期待夯实技术基础的底蕴. 在学习与搜索资料的过程中, 顺便对知乎的一个同学的基础问题, 进行了回复. 不小心回复一下就成了千字文, 觉得挺有趣...
allen_zhan 2023-01-28 11:53
微功率 ISM 频率探讨相关文档组总结
不知不觉, 自开启关于微功率频率的话题起, 即从第一份文章写就到今天总结之日, 已经接近 10 个工作日左右. 早先的想法是对工程界未来的微功率设备相关项目, 从项目规划开始, 对选择系统, 频率, ...
allen_zhan 2023-01-27 22:50
关于 LoRa 应用场景的讨论
说明: 本文中斜体部分表示来自公告文件的部分内容剪贴或合并整理.1. "第52号文" 对 470MHz 的约束引自 如下:(四)民用计量仪表限在建筑楼宇、住宅小区及村庄等小范围内组网应用,任意时刻限...
allen_zhan 2023-01-25 13:24
ISM 频段中 2.4G 与 5.8GHz 设备的使用与限制
说明: 本文中斜体部分表示来自公告文件的部分内容剪贴或合并整理.1. ISM 频段定义中的 2.4G 与 5.8GHz正如同 文中确定的, 2.4G, 5.8GHz 属于中国大陆 ISM 频段的定义...
我要评论
6
18
关闭 站长推荐上一条 /2 下一条