void DMA1_Channel1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_adc1); //这里省略其他处理代码(读DMA值, 环路运算等) HAL_ADC_Stop(&hadc1); HAL_ADC_Start_DMA(&hadc1, (uint32_t *)u32ADC_Value_DMA, 8); } 如上,STM32G474,HRTIM_A触发ADC采样,ADC配置中使能了DMA(normal模式),然后我在DMA中断内获取采样值。 为什么在DMA中断的最后要加stop(ADC)和start(DMA)呢?如果没有这两句话,就无法正常进入该DMA中断。按理说我已经配置了HRTIM_A(65K)触发ADC,ADC会以65K频率自动触发采样,自动进DMA中断。 有没有大神解释一下~ |
STM32G0B1adc+dma采样数据错位
电能变换
求助:PMSM电机编码器线数(分辨率)为80000线,超过MCSDK5.4.8软件所能设置的最大线数65535,请问如何解决
STM32H7打开DCache后,串口1DMA接受数据位空
STM32 SPI从机用DMA方式实现全双工,数据传输过程中出错。
数字电源-G474(三项维也纳):MCU两处外部时钟源设置为 经过运放检测三项电流信号的A B C相的疑问。
关于STM32F4的ADC测量不准确
与HAL_ADC_Start_DMA相关的一个十分怪异的问题
双重ADC的DMA请求
stm32g474 板卡偶发flash的某块代码区被擦除
我这边模拟你的应用场景,做了验证测试。可以重现你的问题。
首先,你现在的DMA工作在Normal模式,每次传输一轮数据后DMA会自动停下来,所以重启DMA是必须的。
但是,你更大的疑惑点可能在于为什么启动ADC的DMA传输要先停止AD模块。
原因就是,当你启动ADC后,数据传输由DMA传输相应个数数据后就停下来了。但AD并没有停下来,而在你目前
调用的API库函数里恰好就有对AD工作状态的检测。见下面代码:
if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL) { tmp_hal_status = HAL_BUSY;return tmp_hal_status; }
如果检查到AD还在工作,则表示此时AD在忙碌,程序没有完成相应初始化而是直接基于busy状态返回退出,所以后续的ADC数据没法完成传输。
强调一下,这是基于库函数的应用逻辑。我们自行组织代码时可能就不一定要这么做。它这么做有好处,
每次开启ADC及DMA传输时尽可能是从头开始,便于数据管理等。
既然DMA配置在Normal模式,DMA每完成一轮数据的传输后会自动停下来。想再使用它的话需重新配置和使能。如果明白了这点,对为什么需要再次[调用启动]()ADC的DMA传输的API函数HAL_ADC_Start_DMA()就可以释怀了。
那另一个疑惑就是,为什么在调用该API函数前还有调用HAL_ADC_Stop()函数关闭ADC呢?
我们可以点进HAL_ADC_Start_DMA()函数里面去看看,可以很快发现在该函数的入口处就有对ADC是否处于运行态的检查。如果检查到当前ADC处于工作态,即busy态就马上退出函数,而不做后续的DMA配置及其它ADC相关处理。
为什么重启ADC的DMA传输要先停掉ADC? (qq.com)
明白了,非常感谢!👍
明白了,非常感谢!👍