使stm32 ADC DMA工作缺少什么?转移竞争不会发生

时间:2017-06-14 07:13:04

标签: stm32 dma adc

我正在使用stm32f3发现板和CubeMX中的HAL。我想在ADC4上使用2个ADC通道。我在循环模式下配置了DMA。在主要的循环中,我打电话:

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;

感谢您的建议。

1 个答案:

答案 0 :(得分:4)

问题在于ADC的时钟为48 MHz,核心时钟仅为12 MHz。函数HAL_DMA_IRQHandler检查第一个中断标志是否为半传输完成,然后是传输完成的样式

if (half transfer complete){
  HAL_ADC_ConvHalfCpltCallback();
} **ELSE** if (transfer complete){
  HAL_ADC_ConvCpltCallback();
}

由于ADC / DMA总是设置半传输中断标志,并且处理器速度很慢,因此核心永远不会进入秒ìf分支,因此永远不会调用ConvCpltCallback()。