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),但未启动转换流程。需要:- 配置连续转换模式:
ADC1->CFGR |= CFGR_CONT; - 启动转换:
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
相关产品推荐
相关产品推荐

