基于STM32F411CE开发板的SWO配置及ITM输出问题求助
STM32F411CE SWO输出无响应问题排查与解决建议
作为STM32工具及微控制器新手,在基于STM32F411CE的开发板上尝试使用SWO功能实现printf输出Hello World,修改了syscalls.c中的ITM_SendChar函数及__write函数,但启动调试后ITM控制台无任何输出,以下是代码及排查建议:
现有代码
main.c
#include <stdint.h> #include <stdio.h> int main(void) { printf("Hello World!"); for(;;); }
syscalls.c 中添加的ITM_SendChar函数
void ITM_SendChar(uint8_t ch) { //Enable TRCENA DEMCR |= ( 1 << 24); //enable stimulus port 0 ITM_TRACE_EN |= ( 1 << 0); // read FIFO status in bit [0]: while(!(ITM_STIMULUS_PORT0 & 1)); //Write to ITM stimulus port0 ITM_STIMULUS_PORT0 = ch; }
修改后的__write函数
__attribute__((weak)) int _write(int file, char *ptr, int len) { (void)file; int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { //__io_putchar(*ptr++); ITM_SendChar(*ptr++); } return len; }
排查与解决建议
1. 硬件与调试器配置
- 确认开发板SWO引脚(STM32F411CE的SWO为PB3)已连接到调试器(如ST-Link)的SWO引脚,部分开发板需通过跳帽启用SWO通路
- 在STM32CubeIDE的Debug Configuration中,进入对应调试会话的Debugger标签页,勾选Enable Trace,设置Trace时钟(需与系统时钟匹配,如STM32F411常用80MHz),并选择SWO作为Trace模式
2. 代码修正
- 需引入Core-M4核心头文件,确保寄存器定义合法,添加:
#include "core_cm4.h" - ITM初始化操作只需执行一次,不要在每次发送字符时重复设置,建议单独写初始化函数:
并在void ITM_Init(void) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; ITM->LAR = 0xC5ACCE55; // 解锁ITM寄存器(部分调试器要求) ITM->TER |= 1UL << 0; // 启用刺激端口0 }main函数开头调用ITM_Init() - 修正
ITM_SendChar中的就绪判断逻辑,正确的等待条件为:while((ITM->PORT[0].u32 & ITM_PORT_U32_Msk) == 0); - 关闭半主机模式:在工程设置的MCU GCC Compiler -> Preprocessor中添加宏定义
SEMIHOSTING_NONE,避免半主机模式干扰printf重定向
3. ITM控制台配置
- 在调试界面打开ITM Console视图,点击配置按钮,设置SWO Port为0,波特率需与调试配置中的Trace时钟匹配(如Trace时钟80MHz时可设为2000000)
- 调试会话启动后,确保ITM控制台已手动连接(部分情况下需点击"Connect"按钮)
修正后完整代码示例
#include <stdint.h> #include <stdio.h> #include "core_cm4.h" void ITM_Init(void) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; ITM->LAR = 0xC5ACCE55; ITM->TER |= 1UL << 0; } void ITM_SendChar(uint8_t ch) { if((ITM->TER & (1UL << 0)) == 0) { return; // 端口未启用则直接返回 } while((ITM->PORT[0].u32 & ITM_PORT_U32_Msk) == 0); ITM->PORT[0].u8 = ch; } __attribute__((weak)) int _write(int file, char *ptr, int len) { (void)file; int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { ITM_SendChar(*ptr++); } return len; } int main(void) { ITM_Init(); printf("Hello World!\n"); for(;;); }
内容的提问来源于stack exchange,提问作者Armando Angulo
相关产品推荐
相关产品推荐

