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