STM32ADC_DMA_UART数据传输
STM32 ADC_DMA_UART data transfer
我正在尝试在 STM32F103C8 微控制器上实现以下场景。
在 PB11 和 PB10 上,我分别连接了 LED 和按钮。 LED 连续闪烁 500 毫秒,但当按下按钮时,它会以 100 毫秒的延迟闪烁 20 次。
我还连接了 UART (PA3-PA2) 和 ADC (PA0) 上的电位器。我的任务是在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);
}
}
对我来说最可能的原因是ADC中断处理程序(包括ST库函数和您提供的回调)触发过于频繁,以至于按钮触发的EXTI的ISR被抑制(永久或几乎永久)。
如果您 select 设置了最小采样时间和连续转换模式,这可能会更容易发生(因为采样和转换会尽可能频繁地发生,并且触发转换完成回调的 IRQ (HAL_ADC_ConvCmpltCallback()) 可能一直 运行。
为了verify/falsify我的假设,请检查
- ADC 和 EXTI(以及您可能在系统上拥有的其他)的中断优先级
- 如果您 select 更长的 ADC 采样周期,或者如果您减慢 ADC 的时钟源(当然不会减慢 CPU 时钟),会发生什么情况。
如果这不能解决您的问题,您可以 post 另一个更完善的问题。
我正在尝试在 STM32F103C8 微控制器上实现以下场景。
在 PB11 和 PB10 上,我分别连接了 LED 和按钮。 LED 连续闪烁 500 毫秒,但当按下按钮时,它会以 100 毫秒的延迟闪烁 20 次。
我还连接了 UART (PA3-PA2) 和 ADC (PA0) 上的电位器。我的任务是在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);
}
}
对我来说最可能的原因是ADC中断处理程序(包括ST库函数和您提供的回调)触发过于频繁,以至于按钮触发的EXTI的ISR被抑制(永久或几乎永久)。
如果您 select 设置了最小采样时间和连续转换模式,这可能会更容易发生(因为采样和转换会尽可能频繁地发生,并且触发转换完成回调的 IRQ (HAL_ADC_ConvCmpltCallback()) 可能一直 运行。
为了verify/falsify我的假设,请检查
- ADC 和 EXTI(以及您可能在系统上拥有的其他)的中断优先级
- 如果您 select 更长的 ADC 采样周期,或者如果您减慢 ADC 的时钟源(当然不会减慢 CPU 时钟),会发生什么情况。
如果这不能解决您的问题,您可以 post 另一个更完善的问题。