本帖最后由 myxiaonia 于 2015-3-12 00:51 编辑
dma实在太强大,stm32f1的crc计算,使用dma传输,在72m主频下,1k次竟然在0.2us内完成。。。。。。。。。。作为对比的软件传递方法,用时128us,这个差距,简直爆出翔了
不敢私藏代码,愿把测试代码奉上,希望对大家有用(计时是用的mdk调试模式时寄存器窗口中的时间值)
- #define CRC_START(src, len) CRC->CR = CRC_CR_RESET;
- {DMA_Channel_TypeDef *ps = DMA2_Channel1;
- while(ps->CCR & DMA_CCR1_EN);
- ps->CMAR = (uint32_t)src;
- ps->CNDTR = len;
- ps->CCR |= DMA_CCR1_EN; }
- void CRC_DMA_Configuration(void)
- {
- RCC->AHBENR |= 0
- | RCC_AHBENR_CRCEN
- | RCC_AHBENR_DMA2EN
- ;
- DMA2_Channel1->CPAR = (uint32_t)&CRC->DR;
- DMA2_Channel1->CCR = 0
- | DMA_CCR1_MEM2MEM //M2M模式传送
- | DMA_CCR1_PLVH //优先级最高
- | DMA_CCR1_MSIZE32 //外设位宽32位
- | DMA_CCR1_PSIZE32 //缓冲区位宽32位
- | DMA_CCR1_MINC //缓冲区地址自增
- // | DMA_CCR1_PINC //外设地址不变
- // | DMA_CCR1_CIRC //非循环模式
- | DMA_CCR1_DIR //存储器到外设
- | DMA_CCR1_TEIE //传输错误中断
- // | DMA_SxCR_HTIE
- | DMA_CCR_TCIE //开启传输完成中断
- // | DMA_SxCR_EN //DMA流使能
- ;
- }
- void DMA2_Channel1_IRQHandler(void)
- {
- DMA_Channel_TypeDef *pch = DMA2_Channel1;
- DMA_TypeDef *pdma = DMA2;
-
- pch->CCR &=~DMA_CCR1_EN;
- pdma->IFCR = DMA_IFCR_CGIF1;
- }
- uint32_t clc_crc(const uint32_t *ptr,uint32_t length)
- {
- CRC->CR=CRC_CR_RESET;
- for( ; length; --length)
- CRC->DR = *ptr++;
- return CRC->DR;
- }
- int main(void)
- {
- NVIC_SetPriority(DMA2_Channel1_IRQn,NVIC_EncodePriority(3,6,0));
- NVIC_EnableIRQ(DMA2_Channel1_IRQn);
- CRC_DMA_Configuration();
- while(1)
- {
- clc_crc((uint32_t *)0x2000c000,1024);
- CRC_START((void *)0x2000c000,1024);
- }
- }
复制代码
整个运行过程只要你用了断点,调试器自带的周期计数就不准了。
正确方法是开个定时器,在crc开启的时候读一次,在dma完成中断里面再读一次相减,得到时间差,在此之间不可有任何调试器断点。
读到时间差后,就可以用调试器断下来看时间数字了,直到这个时候才能有断点。
一周热门 更多>