STM32 ADC_DMA_UART 数据传输

Posted

技术标签:

【中文标题】STM32 ADC_DMA_UART 数据传输【英文标题】:STM32 ADC_DMA_UART data transfer 【发布时间】:2020-05-24 20:24:02 【问题描述】:

我正在尝试在 STM32F103C8 微控制器上实现以下场景。 在 PB11 和 PB10 上,我分别连接了 LED 和 Button。 LED 连续闪烁 500 毫秒,但当按下按钮时,它会以 100 毫秒的延迟闪烁 20 次。 我还在 ADC (PA0) 上连接了 UART (PA3-PA2) 和电位器。我的任务是以 DMA 模式将 ADC 读数传输到 UART。 LED 和按钮中断运行良好,但一旦我添加了 ADC 和 USART 处理代码,它就停止工作了。 您能否建议,我在 ADC-DMA-UART 处理中的错误在哪里,我该如何解决?

来自 Main.c 的片段

//Buffer for ADC.
uint16_t buffer[5];

huart2.Instance->CR3 |= USART_CR3_DMAT;

//Transfer ADC reading to Buffer in DMA.
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)buffer, 5); 

while (1)
  
        //LED blinking
    HAL_GPIO_TogglePin(GPIOB, LED_Pin);
    HAL_Delay(500);
  

//ADC callback function - When buffer is full transfer to UART.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) 
    HAL_DMA_Start_IT(&hdma_usart2_tx, (uint32_t)buffer, (uint32_t)&huart2.Instance->DR, sizeof(buffer));



//Interrupt handler for Button.
void EXTI15_10_IRQHandler(void) 
    HAL_GPIO_EXTI_IRQHandler(BT_Pin);


//Callback function for Button.
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    if(GPIO_Pin == BT_Pin)
        for(volatile int i=20; i>0; i--)
            HAL_GPIO_TogglePin(GPIOB, LED_Pin);
            HAL_Delay(100);
    

【问题讨论】:

所以在你添加//Transfer ADC reading to Buffer in DMA. HAL_ADC_Start_DMA(&hadc1, (uint32_t*)buffer, 5); 之后你就不能再打断 LED 了吗? 是的。在我添加了 DMA 和 ADC 之后。 【参考方案1】:

对我来说最可能的原因是ADC中断处理程序(包括ST库函数和您提供的回调)被触发太频繁,以至于按钮触发的EXTI的ISR被抑制(永久或几乎永久)。

如果您选择了最短采样时间和连续转换模式,这可能会更容易发生(因为采样和转换会尽可能频繁地发生,并且 IRQ 会触发您的转换完成回调 (HAL_ADC_ConvCmpltCallback() ) 可能会一直运行。

为了验证/证伪我的假设,请检查

您的 ADC 和 EXTI 中断优先级(以及您在系统上可能拥有的其他中断优先级) 如果您选择更长的 ADC 采样周期,或者如果您减慢 ADC 的时钟源(当然不会减慢 CPU 时钟),会发生什么情况。

如果这不能解决您的问题,您可以发布另一个经过改进的问题。

【讨论】:

以上是关于STM32 ADC_DMA_UART 数据传输的主要内容,如果未能解决你的问题,请参考以下文章

STM32实例——基于STM32开发板实现传感数据采集-DHT11温湿度采集

stm32f4 如何往外部存储sram写数据

stm32 ad进行对数据采样,怎么获取五秒内的采样数据

stm32 串口发送数组 cpu可以工作吗

STM32F407串口传输

STM32实例——基于STM32开发板实现传感数据采集-DHT11温湿度采集