什么是使stm32 ADC DMA正常工作所缺失的?传输完成未发生。

6

我正在使用一块stm32f3探索板和来自CubeMX的HAL。 我试图在ADC4上使用2个ADC通道。 我配置了循环模式下的DMA。 在main函数的主循环之前,我调用:

HAL_ADC_Start_DMA(&hadc4, DMA_adc4_buffer, 16);

我实现了函数HAL_ADC_ConvHalfCpltCallbackHAL_ADC_ConvCpltCallback。现在奇怪的部分是:HAL_ADC_ConvHalfCpltCallback经常被调用,但HAL_ADC_ConvCpltCallback没有被调用。
这告诉我,使用DMA传输的ADC运行良好。但为什么传输完成回调没有被调用呢? 如果我使用HAL_ADC_Start_IT启动ADC,则会调用中断函数,但这不是我想要的。
在ST HAL中将断点放入HAL_DMA_IRQHandler中也表明,回调从未被调用。
为了完整起见,在此提供ADC4_Init函数的部分代码:
/**Common config 
*/
hadc4.Instance = ADC4;
hadc4.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc4.Init.Resolution = ADC_RESOLUTION_12B;
hadc4.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc4.Init.ContinuousConvMode = ENABLE;
hadc4.Init.DiscontinuousConvMode = DISABLE;
hadc4.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc4.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc4.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc4.Init.NbrOfConversion = 2;
hadc4.Init.DMAContinuousRequests = ENABLE;
hadc4.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc4.Init.LowPowerAutoWait = DISABLE;
hadc4.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

感谢您的想法。

没有通道配置,也没有DMA配置,那你认为它怎么能工作呢? - 0___________
我刚刚在CRC相关的DMA中做了类似的事情。当您设置中断的回调时,必须选择要为其选择哪个事件的回调。对于我来说,我想要完成,因此在回调请求中,我使用了HAL_DMA_XFER_CPLT_CB_ID。最初,我只是在那里放了一个1,结果在DMA进行到一半时就被回调了! - user50619
1个回答

8
问题在于ADC的时钟是48 MHz,而核心时钟只有12 MHz。函数HAL_DMA_IRQHandler先检查半传输完成的中断标志,然后检查传输完成的标志。
if (half transfer complete){
  HAL_ADC_ConvHalfCpltCallback();
} **ELSE** if (transfer complete){
  HAL_ADC_ConvCpltCallback();
}

由于ADC / DMA总是如此快地设置半传输中断标志,而处理器则非常缓慢,所以核心永远不会进入第二个if分支,因此也永远不会调用ConvCpltCallback()。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接