STM32F103在FreeRTOS下串口1中断接收无法进入中断的问题
核心问题定位
问题根源大概率是中断通道命名不匹配导致FreeRTOS中断管理机制无法正确关联中断服务函数,或是中断优先级配置不符合FreeRTOS要求。
具体排查与修复步骤
确认中断服务函数名称正确性
STM32F1系列串口1的中断服务函数名称固定为USART1_IRQHandler,无论使用USART1_IRQn还是USART1_IRQChannel,都必须保证该函数名称准确且未被其他代码覆盖。检查函数定义示例:void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { // 读取接收数据等逻辑 USART_ClearITPendingBit(USART1, USART_IT_RXNE); } }调整中断优先级适配FreeRTOS规则
FreeRTOS要求可屏蔽中断的优先级必须低于configMAX_SYSCALL_INTERRUPT_PRIORITY(在FreeRTOSConfig.h中定义)。STM32优先级数值越小优先级越高,若串口中断优先级设置过高,会导致FreeRTOS无法正常处理。重新配置NVIC:NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5; // 确保低于configMAX_SYSCALL_INTERRUPT_PRIORITY NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);同时确认
FreeRTOSConfig.h中的configPRIO_BITS与STM32F1内核匹配(F1系列为4位优先级,需设置configPRIO_BITS = 4)。补全正确的中断通道宏定义
部分老版本FreeRTOS配套库存在宏定义不规范问题,可手动在代码中补全:#ifndef USART1_IRQn #define USART1_IRQn USART1_IRQChannel // 或直接用固定数值37(STM32F10x中USART1中断号为37) #endif检查全局中断开关状态
确认初始化FreeRTOS或创建任务后,未调用portDISABLE_INTERRUPTS()等全局关中断函数,也未在任务中错误关闭串口1中断。可在中断服务函数开头添加调试动作(如点亮LED),验证是否真的未进入中断。验证中断标志位触发状态
在主循环中轮询USART_GetITStatus(USART1, USART_IT_RXNE),若能读到置位,说明硬件和串口初始化无问题,问题出在中断向量或FreeRTOS中断管理;若读不到,则需重新检查串口中断使能配置(如是否开启USART_IT_RXNE中断)。
内容的提问来源于stack exchange,提问作者xiziduoqiu

