赞
踩
一、在看代码之前先认识几个寄存器:
CNDTR寄存器:标准库中这样写:DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;即配置的BufferSize为CNDTR的值
CPAR寄存器:DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;即配置的源地址(数据的原始地址)
CMAR寄存器:DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;即配置的目标地址(数据的目标地址)
二、上代码:
每次的DMA传输是由两个部分组成的:(正点原子视频里面说的是三个,但我觉得大体上还是两个)
1.两个地址(CPAR和CMAR)之间数据传输
2.传输完成后(即从外设地址取了一次16位数据到内存后),BufferSize(CNDTR)自减
当CNDTR自减到0时,数据传输完成。
三、我在学习过程中的困惑解决(ADC采样且使用DMA中断):
1.一开始无法进入DMA中断:
原因是在初始化时失能了DMA:DMA_Cmd(DMA1_Channel1,DISABLE);
初始化时使能DMA就好了:DMA_Cmd(DMA1_Channel1,ENABLE);
2.两个数据宽度:
如果源端地址宽度=目标地址宽度,如源端地址宽度=目标地址宽度=16,那么源端地址每次偏移为0x2,目标地址每次偏移为0x2。数据没有丢失,即源数据是什么,目标数据就是什么。
如果源端地址宽度>目标地址宽度,如源端地址宽度=16,目标地址宽度=8,那么源端地址每次偏移为0x2,目标地址每次偏移为0x1。且数据会丢失!具体丢失内容可以看上图。
如果源端地址宽度<目标地址宽度,如源端地址宽度=8,目标地址宽度=16,那么源端地址每次偏移为0x1,目标地址每次偏移为0x2。数据没有丢失,但会出现8位数据占16位数据的情况,可以看上图,而此时,配置的左对齐和右对齐就有了作用。
3.BufferSize和DMA模式:
像文章一开始所说,BufferSize的值是写进了CNDTR寄存器。当传输了一次数据后,CNDTR寄存器的值减1,减到0时,数据传输完成。
那么如果我需要一直传输数据怎么办呢?
两个方法:①开启DMA的循环模式,在BufferSize的值减到0时,会重新变为配置值。且此时不需要不断开启和关闭DMA
如:(在ADC采样时开启DMA中断)
②使用DMA普通模式时,需要在DMA中断中开启和关闭DMA,且需要重新设定BufferSize的值
如:
文章到此结束,感觉对你有用的话,点赞收藏喔
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。