
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中断。 有没有大神解释一下~ |
stm32F723ZET6使用ADC捕获正弦波,adc采样频率过高导致主函数无法运行,要怎么优化?
motor profiler参数识别卡在7%是什么原因啊,电机只响不动,手动旋转有阻力,顿感
LIS2MDL X轴数据读取问题
ADC差分采样
STEVAL-PTOOL4A开发板资料求助
STSPIN32G4的AN5432文档资料去哪里找?
开发逆变器进行STM32学习,路径如何规划?
STM32G474如何实现Buck变换器的COT控制模式
关于使用cubemx配置stm32g473re的opamp工作模式:Programmable gain amplifier mode with external filtering
STM32U575 按照历程配置了ADC,参考电压采用默认,Vrefe和VADDA短接,3.3V。ADC引脚有1.8v,读取的结果为0。
我这边模拟你的应用场景,做了验证测试。可以重现你的问题。
首先,你现在的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)
明白了,非常感谢!👍
明白了,非常感谢!👍