F4 ADC+DMA的归纳整理与疑问

2019-07-21 04:19发布

经过多次尝试,个人总结了一下F4的ADC+DMA,但由于本人水平有限,该方面内容还没完全明白,而且贴中内容可能会有错误,希望各位高手老手不吝赐教。
1.F4比F0的ADC_SR寄存器多了一位!是bit5 OVR位,参考手册似乎并没有详细描述,只是说是错误(溢出)检测标志。因为这一位,本人曾多次尝试移植F3的程序都不能成功。

2.官方解释:
位5 OVR:溢出(Overrun)
数据丢失时,硬件将该位置1(在单一模式或双重/三重模式下)。但需要通过软件清零。溢 
出检测仅在DMA = 1 或EOCS = 1 时使能。
0:未发生溢出 
1:发生溢出

11.8  数据管理
11.8.1  使用DMA
由于规则通道组只有一个数据寄存器,因此,对于多个规则通道的转换,使用DMA 非常有 
帮助。这样可以避免丢失在下一次写入之前还未被读出的ADC_DR 寄存器中的数据。
在使能DMA 模式的情况下(ADC_CR2 寄存器中的DMA 位置1), 每 完 成 规 则 通 道 组 中 的 
一个通道转换后,都会生成一个DMA 请求。这样便可将转换的数据从ADC_DR 寄 存 器 传 输 
到用软件选择的目标位置。
尽管如此,如果数据丢失(溢出),则会将ADC_SR 寄存器中的OVR 位置1 并 生 成 一 个 中 
断(如果OVRIE 使能位已置1)。随后会禁止DMA 传输并且不再接受DMA 请 求 。 在 这 种 
情况下,如果生成DMA 请求,则会中止正在进行的规则转换并忽略之后的规则触发。随后 
需要将所使用的DMA 流中的OVR 标志和DMAEN 位清零,并重新初始化DMA 和ADC, 
以将需要的转换通道数据传输到正确的存储器单元。只有这样,才能恢复转换并再次使能数
据传输。注入通道转换不会受到溢出错误的影响。
在DMA 模式下,当OVR = 1 时,传送完最后一个有效数据后会阻止DMA 请求,这意味着
传输到RAM 的所有数据均被视为有效。
在最后一次DMA 传输(DMA 控制器的DMA_SxRTR 寄存器中配置的传输次数)结束时:
● 如果将ADC_CR2 寄存器中的DDS 位清零,则不会向DMA 控制器发出新的DMA 请 求 
(这可避免产生溢出错误)。不过,硬件不会将DMA 位清零。必须将该位写入0 然 后 
写入1 才能启动新的传输。
● 如果将DDS 位置1,则可继续生成请求。从而允许在双缓冲区循环模式下配置DMA。
要在使用DMA 时将ADC 从OVR 状态中恢复,请按以下步骤操作:
1. 重新初始化DMA(调整目标地址和NDTR 计数器)
2.  将ADC_SR 寄存器中的ADC OVR 位清零
3.  触发ADC 以开始转换。

实际中发现,不知为什么启动DMA后OVR总会总会置1,于是只能按参考手册说的重新启动DMA(DMA为循环模式): [mw_shl_code=c,true] ADC1->SR&=~(1<<5); ADC1->CR2&=~(1<<8); //关闭DMA ADC1->CR2|=1<<8; //使能DMA Show_Adc(134,150,vlaue_adc); ADC_FrameEnable();//即使在连续模式下,也必须重新启动ADC[/mw_shl_code] 若DMA不为循环模式,还要清中断标志位: [mw_shl_code=c,true]MYDMA_Enable(DMA2_Stream0,1); while(!DMA2->LISR&(1<<5)) ; //等待 DMA2_Steam0 传输完成 DMA2->LIFCR|=1<<5; //清除 DMA2_Steam7 传输完成标志 ADC1->SR&=~(1<<5); ADC1->CR2&=~(1<<8); //关闭DMA ADC1->CR2|=1<<8; //使能DMA Show_Adc(134,150,vlaue_adc); ADC_FrameEnable();[/mw_shl_code] 这样写的话,单通道ADC的值可以读出,若是多通道的话还没有试。
所以疑问来了:
1.OVR标志位究竟是什么意思?什么时候溢出?
2.我这样的复位写法对吗?



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。