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条回答
redroof
2019-12-18 15:15
myxiaonia 发表于 2015-3-13 09:18
其实我就是用了中断断点,在dma完成中断入口下断点,在dma crc开启的最后一个代码处全速运行,这样就可以 ...

整个运行过程只要你用了断点,调试器自带的周期计数就不准了。
正确方法是开个定时器,在crc开启的时候读一次,在dma完成中断里面再读一次相减,得到时间差,在此之间不可有任何调试器断点。
读到时间差后,就可以用调试器断下来看时间数字了,直到这个时候才能有断点。

一周热门 更多>