本文开发环境:
- MCU型号:STM32F103ZE
- IDE环境: MDK 5.27
- 调试器:ST-LINK
本文内容:
- 使用 ITM 输出调试信息
一、ITM 简介
开发STM32的时,我们通常使用串口(uart)作为调试工具,但是其需占用一个串口资源,而且现在的计算机由于没有uart接口,还需要一个USB转串口模块。事实上,我们可以使用调试器ST-LINK(本文使用调试器)或是J-LINK,来进行数据的输出。如下图所示:
如果你没有使用IDE开发环境,那么使用ST-LINK上位机软件也可以查看,注意系统时钟 System clock 需要和你的硬件MCU匹配:
二、ITM 输出功能的配置和使用
本文以ST-LIINK为例示例如何使用ITM的打印功能来调试STM32。
1. 硬件连接
如果我们要下载程序,那么最简单地将SWDIO,SWCLK,GND连接STM32即可,但是如果要使用信息打印功能,我们还需要连接SWO口,所以我们需要保证所使用的ST-LINK下载器已经预留出SWO口。如下图所示:
由于本文使用排线,所以不需要关注那么许多,如果你使用杜邦线,请确保连线的正确。
2. printf 函数的重映射
在 main.c (也可以是其他的 .c 文件)重映射printf 到 ITM :
... ...
int fputc(int ch,FILE *f)
{
ITM_SendChar(ch);
return (ch);
}
... ..
这里需要确定一点,在本文的环境中,输出一个字符的接口函数为 int fputc(),但不能保证在其他编译环境(IDE或编译器不同)仍然使用该函数,所以需要你根据具体环境自行确定,MDK环境还需要确认 Use MircoLIB 库是勾选状态。
以上的操作都是为了确保printf()函数最后调用的是我们重映射的函数而已,这和重映射到串口打印的原理是相同的,如果你已经可以使用串口打印数据,那么直接将TIM_SendChar() (同理你需要保证你工程中该函数可以使用SL-LINK发送一个字符)替换原来的串口字符输出函数即可。
在本文使用的环境中,TIM_SendChar(),是通过ITM的通道0打印一个字符,其定义如下:
__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
{
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */
{
while (ITM->PORT[0U].u32 == 0UL)
{
__NOP();
}
ITM->PORT[0U].u8 = (uint8_t)ch;
}
return (ch);
}
3. MDK IDE环境的配置
接下里需要配置Trance的功能,首先在MDK工具栏中点开options for target 按钮:
在弹出窗口中,点击调试器的Settings
按钮:
进入Trance调试选项卡,时钟需要根据的所使用的芯片为准,设置错误导致的结果与串口波特率不对类似,如题操作如下所示:
4. 编写调试代码
测试代码是简单的,可以在mian.c中写入循环打印的语句,来验证程序:
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(500);
printf(":D Welcome to My Blog! \r\n");;
}
/* USER CODE END 3 */
5. 功能验证
首先进入MDK调试debug硬件调试功能:
接着调出观察窗口,View ->Serial Windows -> Debug(printf)Viewer 具体配置如下所示:
窗口打开以后,就可以运行程序,在 Debug(printf)Viewer 中观察到数据了,如下图所示: