You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F091RC ADC中断模式配置故障:回调函数未触发

问题:STM32F091RC ADC中断回调函数未触发排查

我正尝试将STM32F4的ADC中断配置代码移植到STM32F091RC,配置ADC为中断模式后,中断处理函数中的adc_callback始终未被调用。曾尝试通过检查EXTI挂起位来触发回调并清除挂起标志,但问题仍未解决,恳请协助排查。

相关代码

初始化代码

#define ADCENABLE       (1U<<9)
#define GPIOAENABLE     (1U<<17)
#define ADC_CH1         (1U<<1)
#define CR_ADEN         (1U<<0)
#define CFGR_CONT       (1U<<13)
#define CR_EOCIE        (1U<<2)


void pa1_adc_interrupt_init(void)
{
    /* Configure the ADC GPIO Pin */
    /* Enable Clock access to gpioa */
    RCC->AHBENR |= GPIOAENABLE;
    /* Set the mode of PA1 to analog mode */
    GPIOA->MODER |= (1<<2);
    GPIOA->MODER |= (1<<3);

    /* Configure the ADC module */
    /* Enable clock access to ADC */
    RCC->APB2ENR |= ADCENABLE;

    /* Enable ADC end-of-conversion interrupt */
    ADC1->IER |= CR_EOCIE;

    /* Setting Priority */
    //NVIC_SetPriority(ADC1_COMP_IRQn, 0);

    /* Enable ADC interrupt in NVIC */
    NVIC_EnableIRQ(ADC1_COMP_IRQn);

    /* Configure adc parameters */
    /* Conversion sequence start */
    ADC1->CHSELR = ADC_CH1;

    /* Conversion sequence length */
    /* Enable ADC module */
    ADC1->CR |= CR_ADEN;
}

中断处理与回调函数

static void adc_callback(void)
{
    sensor_value = ADC1->DR;
    printf("the sensor value is %d \n\r", (int)sensor_value);
}

void ADC_COM_IRQHandler(void)
{
    /* Check for eoc in SR */
    /*
    if(ADC1->ISR & ADC_EOC)
    {
//       Clear EOC
        ADC1->ISR &= ~ADC_EOC;
        // doing sth here
        adc_callback();
    }
    */

    if(EXTI->PR & (1U<<21))
    {
        adc_callback();
        val = 1;
        EXTI->PR |= (1U<<21);
    }
}

核心问题与修正方案

  • 中断服务函数名称错误
    STM32F0系列中,ADC对应的中断服务函数名称是ADC1_COMP_IRQHandler,但你写的是ADC_COM_IRQHandler,名称不匹配导致中断触发后无法进入正确的处理函数。直接将函数名改为ADC1_COMP_IRQHandler即可。

  • 错误使用EXTI寄存器判断ADC中断
    STM32F0的ADC中断标志位存储在ADC自身的ISR寄存器中,和EXTI无关。你注释掉的检查ADC1->ISR & (1U<<2)(EOC位)才是正确的判断逻辑,恢复这段代码并删除EXTI相关的错误判断。注意清除EOC标志需要写1到ISR的EOC位(ADC1->ISR |= (1U<<2),STM32F0的ADC标志位是写1清除,不是写0)。

  • 缺少ADC启动转换的步骤
    你仅开启了ADC模块(CR_ADEN),但未启动转换流程。需要:

    1. 配置连续转换模式:ADC1->CFGR |= CFGR_CONT;
    2. 启动转换:ADC1->CR |= (1U<<2);(ADSTART位)
  • 缺失ADC校准步骤
    STM32F0的ADC在启用后需要执行校准,否则可能无法正常工作。在开启ADC(CR_ADEN)后添加以下代码:

    // 等待ADC就绪
    while(!(ADC1->ISR & (1U<<0)));
    // 启动校准
    ADC1->CR |= (1U<<3);
    // 等待校准完成
    while(ADC1->CR & (1U<<3));
    
  • 宏定义补充
    确保ADC_EOC宏正确定义,比如添加:#define ADC_EOC (1U<<2),避免编译错误。

内容的提问来源于stack exchange,提问作者persona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:07:33