dma crc,令人吃惊的性能,计算1k个值竟然在0.2us内完成

2019-12-13 18:23发布

本帖最后由 myxiaonia 于 2015-3-12 00:51 编辑

dma实在太强大,stm32f1的crc计算,使用dma传输,在72m主频下,1k次竟然在0.2us内完成。。。。。。。。。。作为对比的软件传递方法,用时128us,这个差距,简直爆出翔了

不敢私藏代码,愿把测试代码奉上,希望对大家有用(计时是用的mdk调试模式时寄存器窗口中的时间值)

  1. #define CRC_START(src, len)     CRC->CR = CRC_CR_RESET;                 
  2.                                {DMA_Channel_TypeDef *ps = DMA2_Channel1;  
  3.                                                                 while(ps->CCR & DMA_CCR1_EN);   
  4.                                 ps->CMAR         = (uint32_t)src;   
  5.                                 ps->CNDTR         = len;            
  6.                                 ps->CCR     |= DMA_CCR1_EN; }


  7. void CRC_DMA_Configuration(void)
  8. {
  9.     RCC->AHBENR          |= 0
  10.                          | RCC_AHBENR_CRCEN
  11.                          | RCC_AHBENR_DMA2EN
  12.                          ;
  13.     DMA2_Channel1->CPAR   = (uint32_t)&CRC->DR;
  14.         DMA2_Channel1->CCR         = 0
  15.                          | DMA_CCR1_MEM2MEM              //M2M模式传送
  16.                          | DMA_CCR1_PLVH                 //优先级最高
  17.                          | DMA_CCR1_MSIZE32              //外设位宽32位
  18.                          | DMA_CCR1_PSIZE32              //缓冲区位宽32位
  19.                          | DMA_CCR1_MINC                //缓冲区地址自增
  20. //                         | DMA_CCR1_PINC                //外设地址不变
  21. //                         | DMA_CCR1_CIRC                //非循环模式
  22.                          | DMA_CCR1_DIR                 //存储器到外设
  23.                          | DMA_CCR1_TEIE                //传输错误中断
  24. //                         | DMA_SxCR_HTIE
  25.                          | DMA_CCR_TCIE                //开启传输完成中断
  26. //                         | DMA_SxCR_EN                  //DMA流使能
  27.                          ;
  28. }


  29. void DMA2_Channel1_IRQHandler(void)
  30. {
  31.     DMA_Channel_TypeDef *pch = DMA2_Channel1;
  32.     DMA_TypeDef *pdma = DMA2;
  33.    
  34.     pch->CCR    &=~DMA_CCR1_EN;
  35.     pdma->IFCR   = DMA_IFCR_CGIF1;
  36. }

  37. uint32_t clc_crc(const uint32_t *ptr,uint32_t length)
  38. {
  39.         CRC->CR=CRC_CR_RESET;
  40.         for( ; length; --length)
  41.                 CRC->DR = *ptr++;
  42.         return CRC->DR;
  43. }

  44. int main(void)
  45. {
  46.     NVIC_SetPriority(DMA2_Channel1_IRQn,NVIC_EncodePriority(3,6,0));
  47.         NVIC_EnableIRQ(DMA2_Channel1_IRQn);
  48.         CRC_DMA_Configuration();
  49.         while(1)
  50.         {
  51.                 clc_crc((uint32_t *)0x2000c000,1024);
  52.                 CRC_START((void *)0x2000c000,1024);
  53.         }
  54. }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
40条回答
liubin1109
1楼-- · 2019-12-16 03:43
lryxr2507 发表于 2015-3-12 08:13
收藏.可怜的电工.睡得比狗晚,起的比鸡早.

应该是睡得比鸡晚
huangqi412
2楼-- · 2019-12-16 07:48
72M, 1US只有72个时钟啊,
huangqi412
3楼-- · 2019-12-16 12:30
0.2US岂不是只有10多个时钟
myxiaonia
4楼-- · 2019-12-16 15:10
 精彩回答 2  元偷偷看……
huangqi412
5楼-- · 2019-12-16 17:10
myxiaonia 发表于 2015-3-12 14:37
所以我也觉得很神奇,关键是调试模式下就是那么点时间就完成了,计算的crc值和软件方法一样 我也是醉了   ...

额,为何不是用定时器记录时间。
wye11083
6楼-- · 2019-12-16 22:58
myxiaonia 发表于 2015-3-12 09:09
不行的,f1的是以太网crc32,而且要真正兼容以太网crc的话,传输字节序还要调整,相当麻烦

飞思卡尔的cr ...

曾经花了一些时间研究CRC,1位CRC改一下字就行了,通常在传输过程中就算好了。并行的则一般用于后校验用。8位CRC字每周期出1字节,占256字(字,不是字节,32位CRC要占1KB),几乎没有16位并行的吧,要占256KB,而且没有加快多少。估计NAND,GMII用8位并行,RGMII用4位并行。其实多位并行的原理很简单,就是单位计算N步然后提特征字。超过8位的,我感觉是用了双倍时钟去算的,要不然表占的内存绝对会让人头疼。

一周热门 更多>