<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > STM32F10x 學(xué)習筆記4(CRC計算單元 續)

STM32F10x 學(xué)習筆記4(CRC計算單元 續)

作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò ) 收藏
上篇博客給出了 STM32F10X 系列單片機CRC 單元的用法。還指出了這個(gè)CRC 單元計算的結果與常見(jiàn)的CRC32 算法得到的結果不相同。但是為什么不相同,是什么原因造成的卻沒(méi)有寫(xiě)出來(lái)。這里再補一篇,把這些都說(shuō)清楚。

本文引用地址:http://dyxdggzs.com/article/201611/318839.htm

下面先給個(gè)crc32的計算函數,這個(gè)函數計算的結果與STM32F單片機上硬件單元的計算結果相同。

  1. uint32_tcrc32(uint32_t*addr,intnum,uint32_tcrc)
  2. {
  3. inti;
  4. for(;num>0;num--)
  5. {
  6. crc=crc^(*addr++);
  7. for(i=0;i<32;i++)
  8. {
  9. if(crc&0x80000000)
  10. crc=(crc<<1)^POLY;
  11. else
  12. crc<<=1;
  13. }
  14. crc&=0xFFFFFFFF;
  15. }
  16. return(crc);
  17. }

在我寫(xiě)的文章《寫(xiě)給嵌入式程序員的循環(huán)冗余校驗(CRC)算法入門(mén)引導》(http://blog.csdn.net/liyuanbhu/article/details/7882789)中給了個(gè)利用查表法計算crc的程序。那個(gè)程序稍微修改一點(diǎn)就能計算CRC32。下面給出改動(dòng)后的程序。

  1. //crc32.h
  2. #ifndefCRC32_H_INCLUDED
  3. #defineCRC32_H_INCLUDED
  4. #ifdef__cplusplus
  5. #if__cplusplus
  6. extern"C"{
  7. #endif
  8. #endif/*__cplusplus*/
  9. #include
  10. /*
  11. *TheCRCparameters.CurrentlyconfiguredforCRC32.
  12. *CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+X0
  13. */
  14. #definePOLYNOMIAL0x04C11DB7
  15. #defineINITIAL_REMAINDER0xFFFFFFFF
  16. #defineFINAL_XOR_VALUE0x00000000
  17. /*
  18. *ThewidthoftheCRCcalculationandresult.
  19. *Modifythetypedefforan8or32-bitCRCstandard.
  20. */
  21. typedefuint32_twidth_t;
  22. #defineWIDTH(8*sizeof(width_t))
  23. #defineTOPBIT(1<<(WIDTH-1))
  24. /**
  25. *InitializetheCRClookuptable.
  26. *ThistableisusedbycrcCompute()tomakeCRCcomputationfaster.
  27. */
  28. voidcrcInit(void);
  29. /**
  30. *ComputetheCRCchecksumofabinarymessageblock.
  31. *@paramessage,用來(lái)計算的數據
  32. *@paranBytes,數據的長(cháng)度
  33. *@noteThisfunctionexpectsthatcrcInit()hasbeencalled
  34. *firsttoinitializetheCRClookuptable.
  35. */
  36. width_tcrcCompute(unsignedchar*message,unsignedintnBytes,width_tremainder);
  37. #ifdef__cplusplus
  38. #if__cplusplus
  39. }
  40. #endif
  41. #endif/*__cplusplus*/
  42. #endif//CRC32_H_INCLUDED

對應的C程序如下:

  1. #include"crc32.h"
  2. /*
  3. *Anarraycontainingthepre-computedintermediateresultforeach
  4. *possiblebyteofinput.Thisisusedtospeedupthecomputation.
  5. */
  6. staticwidth_tcrcTable[256];
  7. /**
  8. *InitializetheCRClookuptable.
  9. *ThistableisusedbycrcCompute()tomakeCRCcomputationfaster.
  10. */
  11. voidcrcInit(void)
  12. {
  13. width_tremainder;
  14. width_tdividend;
  15. intbit;
  16. /*Performbinarylongdivision,abitatatime.*/
  17. for(dividend=0;dividend<256;dividend++)
  18. {
  19. /*Initializetheremainder.*/
  20. remainder=dividend<<(WIDTH-8);
  21. /*ShiftandXORwiththepolynomial.*/
  22. for(bit=0;bit<8;bit++)
  23. {
  24. /*Trytodividethecurrentdatabit.*/
  25. if(remainder&TOPBIT)
  26. {
  27. remainder=(remainder<<1)^POLYNOMIAL;
  28. }
  29. else
  30. {
  31. remainder=remainder<<1;
  32. }
  33. }
  34. /*Savetheresultinthetable.*/
  35. crcTable[dividend]=remainder;
  36. }
  37. }/*crcInit()*/
  38. /**
  39. *ComputetheCRCchecksumofabinarymessageblock.
  40. *@paramessage,用來(lái)計算的數據
  41. *@paranBytes,數據的長(cháng)度
  42. *@noteThisfunctionexpectsthatcrcInit()hasbeencalled
  43. *firsttoinitializetheCRClookuptable.
  44. */
  45. width_tcrcCompute(unsignedchar*message,unsignedintnBytes,width_tremainder)
  46. {
  47. unsignedintoffset;
  48. unsignedcharbyte;
  49. //width_tremainder=INITIAL_REMAINDER;
  50. /*Dividethemessagebythepolynomial,abyteatatime.*/
  51. for(offset=0;offset
  52. {
  53. byte=(remainder>>(WIDTH-8))^message[offset];
  54. remainder=crcTable[byte]^(remainder<<8);
  55. }
  56. /*ThefinalremainderistheCRCresult.*/
  57. return(remainder^FINAL_XOR_VALUE);
  58. }/*crcCompute()*/

不過(guò)用這個(gè)程序直接計算得到的CRC值與STM32給出的并不相同。之所以會(huì )這樣是因為字節序的原因??梢耘e個(gè)例子來(lái)說(shuō)明這個(gè)問(wèn)題。比如我們有一片內存區域要計算CRC值。這片內存區域的起始地址是0x1000,共有8個(gè)字節。用crcCompute()函數計算時(shí)是按照地址順序依次傳入各個(gè)字節。也就是先計算0x1000處的字節,再計算0x0001處的字節,以此類(lèi)推最后計算0x1007地址處的字節。而STM32的硬件CRC單元是以32位的字為單位計算的。我們知道CRC實(shí)際上是個(gè)多項式的除法運算,而除法運算是從高位算起的。也就是相當于它是按照0x1003、0x1002、0x1001、0x1000這個(gè)順序計算第一個(gè)字,然后按照0x1007、0x1006、0x1005、x1004的順序計算第二個(gè)字。因此。我們要是預先將字節序調換一下得到結果就沒(méi)有問(wèn)題了。這就有了下面的改造。其中remainder傳入0xffffffff。因為STM32中的CRC余數初始值為0xffffffff。

  1. uint32_tstm32crc32(uint32_t*message,unsignedintnWords,uint32_tremainder)
  2. {
  3. unsignedintoffset;
  4. unsignedcharbyte;
  5. unsignedchar*p=(unsignedchar*)message;
  6. //width_tremainder=INITIAL_REMAINDER;
  7. /*Dividethemessagebythepolynomial,abyteatatime.*/
  8. for(offset=0;offset
  9. {
  10. byte=(remainder>>(WIDTH-8))^p[3];
  11. remainder=crcTable[byte]^(remainder<<8);
  12. byte=(remainder>>(WIDTH-8))^p[2];
  13. remainder=crcTable[byte]^(remainder<<8);
  14. byte=(remainder>>(WIDTH-8))^p[1];
  15. remainder=crcTable[byte]^(remainder<<8);
  16. byte=(remainder>>(WIDTH-8))^p[0];
  17. remainder=crcTable[byte]^(remainder<<8);
  18. p+=4;
  19. }
  20. /*ThefinalremainderistheCRCresult.*/
  21. return(remainder);
  22. }/*crcCompute()*/

大家可以驗證這個(gè)函數的計算結果與STM32上的結果完全一樣。

寫(xiě)到這里本該就結束了,不過(guò)我要多說(shuō)一句,之所以要這么麻煩的調換字節序,都是小端(littleendian)惹的禍。要是都采用大端格式就沒(méi)這些麻煩的轉換了。



關(guān)鍵詞: STM32F10xCRC計算單

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>