ADC中断只进一次

ADC中断只进一次,问题出在CubeMX这个配置
现象
FOC工程移植完之后,串口通了,LED也正常闪,但电机就是不转。在ADC回调里加了个计数器,发现数字一直是1,不再增长。

c
volatile int adc_isr_count = 0;

void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
{
adc_isr_count++;
// ...
}
串口打印显示:adc_isr_count 永远停在1。

这意味着:ADC中断只被触发了一次,之后就再也没进过中断。

ADC中断是FOC算法的心跳。它不跳,Clarke、Park、PID、SVPWM这些代码一行都不会执行。

排查过程
第一步:确认TIM1在跑
用示波器测PA8(TIM1_CH1),有PWM方波输出,说明TIM1计数器在正常运行。

既然TIM1在跑,TRGO应该也在产生。问题可能出在ADC没有正确接收触发信号。

第二步:对比参考工程的adc.c
把商家提供的能正常运行的例程和自己的工程逐行对比,发现关键差异在注入组的触发源配置上。

参考例程:

c
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T1_TRGO;
我的工程:

c
sConfigInjected.ExternalTrigInjecConv = ADC_INJECTED_SOFTWARE_START;
我的ADC配置成了软件触发,不是TIM1 TRGO硬件触发。

为什么软件触发只进一次
软件触发模式下,只有主动调用 HAL_ADCEx_InjectedStart_IT() 时才会触发一次转换。之后如果没有再次调用,ADC就永远不会再采样。

看我的代码:

c
HAL_ADCEx_InjectedStart_IT(&hadc1); // 触发一次
HAL_ADCEx_InjectedStart(&hadc2);
// 之后没有再次调用
所以:

text
执行 HAL_ADCEx_InjectedStart_IT → ADC采样一次 → 进一次中断
之后再无触发源 → 中断永远不再进
整个ADC回调变成了一次性的,FOC算法跑了一轮就停了。

硬件触发和软件触发的区别
触发方式 触发源 特点
软件触发 代码调用HAL_ADCEx_InjectedStart 只能触发一次,需要重复调用
硬件触发 TIM1 TRGO信号 每个PWM周期自动触发,无需CPU干预
FOC需要每个PWM周期采样一次电流,所以必须用硬件触发。

正确的硬件触发链路
text
TIM1计数器跑到特定时刻
↓ 硬件自动产生TRGO脉冲
ADC1/ADC2收到触发信号
↓ 硬件自动开始采样
采样完成
↓ 触发ADC中断
进入HAL_ADCEx_InjectedConvCpltCallback
整个链路全由硬件自动完成,CPU只需要处理最后的中断。