原创 有点鸡肋的PIC硬件CRC模块

2010-3-25 13:34 3545 9 12 分类: MCU/ 嵌入式
Microchip 所有的16单片机都支持硬件CRC功能,这是它的一个特点,低端的MCU带有16位的CRC模块,中高端的则是32位的CRC模块。使用硬件CRC,可以快速计算CRC校验,在存在大数据量通信的情况下,可以加速计算的速度,减少MCU因为软件计算带来额外的开销。

这是AN1148中,硬件CRC和软件CRC计算速度的一个对比:



Case 1: Software Implementation Process


        100 bytes = 800 bits
        1 bit = 8 clock cycles
        800
bits = 6400 clock cycles


Case 2: Hardware Module


        100 bytes = 800 bits
        1 bit = 1 clock cycle
        800
bits = 800 clock cycles


从中可以看到,速度上硬件CRC是软件CRC的8倍。


 


库函数


在 Microchip C30
编译器中,包含了CRC的库函数,它在"crc.h"和"ecrc.h"这两个文件中进行了声明,它们分别对应了16位和32位的硬件CRC模块。主要的库函数分别是:



CRC_Calc_ChecksumWord、CRC_Calc_ChecksumByte


ECRC_Calc_ChecksumLong、ECRC_Calc_ChecksumWord、ECRC_Calc_ChecksumByte

只要初始化后,就可以计算校验值。


 


分析


不过这个CRC模块使用起来也有一些小问题。我们以最常用的8位数据的CRC计算为例,让我们先看一看在应用笔记AN1148中的CRC计算函数,这个函数是Microchip官方提供的一个例子,应该也是C30库函数的原型:




unsigned int CRC_HW_calculateB(unsigned char
*temp,
unsigned int Len)
{


  unsigned int
Carry,j;
  
unsigned
char
*ptr,Flag;
  ptr=(
unsigned char *)&CRCDAT;


  CRCCON = 0x0000F; // ="Length of
polynomial-1"
  CRCXOR = 0x1021; // generator Polynomial
  CRCWDAT=
0x0000; // Initialize CRCWDAT with 0
  Flag=0x00;


  for(j=0;j<Len;j++)
  {
    *ptr =*temp++; //write data into
FIFO
    Flag=Flag^0x01;//Flag for odd or even bytes


    if(CRCCONbits.CRCFUL==1)//check if FIFO is
full
    {
      CRCCONbits.CRCGO=1; //start CRC
engine
      
while(CRCCONbits.CRCMPT!=1);//check if FIFO is
empty
      CRCCONbits.CRCGO=0; //stop CRC engine
    }
  }


  if(CRCCONbits.CRCGO!=1)
    CRCCONbits.CRCGO=1;


  if(Flag==0)
    CRCDAT = 0x0000;
//appending PLEN+1 zeros (multiply by 2^16)
  
else
    *ptr=0x00;//appending (PLEN+1)/2 zeros (multiply by
2^8)


  while(CRCCONbits.CRCMPT!=1);//check if FIFO is empty


    Nop();
    Nop();
    Nop();
    Nop();
    Nop();


  CRCCONbits.CRCGO=0; //stop CRC
engine


    Nop();


  if(Flag==1) // if odd number of
bytes,
  { //append (PLEN+1)/2 zeros (multiply by 2^8)


    for(j = 0; j < 8; j
++)
    {
      Carry =( CRCWDAT & 0x8000);
      CRCWDAT
<<= 1;


      if(Carry)
        CRCWDAT ^= 0x1021;
    }
  }


  return CRCWDAT;


}


 


 


因为是16位单片机,所以内部数据总线是16位的,这样在计算基于字节方式的数据(8bit)时,反而非常不方便。如果是计算的数据是偶数字节还好办,可以正好两个字节放入一个16位寄存器中;如果是奇数个,那么就会多出一个字节,还是需要通过软件的方式进行计算。这样不但显示有些重复,而且从代码效率上来说就显得比较低了,比纯软件方式代码还大,除非有大量的数据需要计算,否则看起来有些得不偿失。


 


参考资料



  • Microchip应用笔记AN1148:Cyclic Redundancy Check (CRC)
  • PIC24FJ64GA004数据手册:39881D.pdf
  • PIC24FJ64GB004数据手册:39940c.pdf

 


PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1024274 2010-5-2 20:03

实际应用中,工程师们都喜欢丢弃CRC功能,他们只关心眼前功能的实现,丝毫不关心恶劣环境下通信可能导致的失效。

用户1483310 2010-3-26 09:28

学习了

用户120337 2010-3-25 20:21

学习一下
相关推荐阅读
shaoziyang 2017-12-15 11:06
《micropython 入门指南》正式出版了
第一本专门介绍MicroPython的中文图书《MicroPython入门指南》由电子工业出版社正式出版了(各大书店和网络书店都有)。MicroPython是近年开源社区中最热门的项目之一,它功能强大...
shaoziyang 2017-11-01 15:30
《MicoPython入门指南》一书即将发行
《MicoPython入门指南》一书即将发行,这是第一本专业介绍MicroPython的中文书籍,请大家多关注和支持。​​...
shaoziyang 2017-07-13 19:50
micro:bit 专用电池扩展板
最近Microbit这么火,就想着要做点什么,于是就有了这个Microbit的专用电池扩展板。它完美配合原版的microbit,可以为microbit增加电池、蜂鸣器功能,功能上超过 MI:power...
shaoziyang 2017-06-13 09:09
用pyboard的dac播放音乐
官方的PyBoard带有DAC功能,使用DAC,我们可以播放简单的音乐。 先准备好两根铜丝,一个有源音箱,一个音频线。 然后从官方网站下载两个文件: http://micropython.org/...
shaoziyang 2017-06-13 09:03
microbit巡线小车 BoBBoT
BoBBoT 是一个使用 BBC micro:bit 控制的巡线小车套件,它很容易组装。 它特别为儿童设计,让孩子可以通过实践学习计算机科学概念。使用 BoBBoT 可以学习: 算法设计 (流程图和...
shaoziyang 2017-06-12 08:29
micropython升级到了 1.9.1
micropython升级到了 1.9.1,主要改进有: v1.9.1 修复了 stm32 的 USB 存储, lwIP 绑定和 VFS 问题 This release provides an imp...
EE直播间
更多
我要评论
3
9
关闭 站长推荐上一条 /3 下一条