> 技术文档 > 单片机 - STM32F103“复用功能重映射”完整解析:从JTAG释放到TIM重映射实战详解_gpio复用tim

单片机 - STM32F103“复用功能重映射”完整解析:从JTAG释放到TIM重映射实战详解_gpio复用tim


本文将详细讲解 STM32F103 系列中常见的“复用功能重映射”(Remap)机制,包括 JTAG 占用、引脚默认功能与复用功能的关系,以及如何通过寄存器或标准库代码实现重映射。以 TIM3 在 PB4/PB5 上输出 PWM 为例,进行实战讲解,适合初学者与进阶开发者参考

一、什么是“复用功能重映射”(Remap)

STM32 系列的引脚大多数都具有多种功能,比如既可以做普通 GPIO,也可以作为串口、定时器通道、SPI 等外设使用。

STM32F103 为例,有些引脚在芯片上电复位后默认配置为某些外设功能(主功能),而有些引脚默认不是该功能,但可以通过“功能重映射”将该功能映射过去。

功能重映射机制允许我们在引脚资源有限或外设冲突时,将某些外设的引脚重新映射到其他引脚组,从而获得更大的灵活性。

二、判断是否需要重映射的逻辑

在使用某个外设功能时,我们需要判断是否可以直接使用,还是必须进行重映射。以下是准确的判断逻辑:

1. 如果“主功能名 == 引脚名”

例如:

  • PA9USART1\\_TX(默认功能)
  • PA10USART1\\_RX(默认功能)

这类引脚默认即可作为对应外设使用,无需任何重映射设置。

2. 如果“主功能名 ≠ 引脚名”,但手册中支持通过重映射映射到该引脚

例如:

  • PB4 默认是 JNTRST,但支持通过重映射成为 TIM3\\_CH1

则必须开启相应的重映射配置,才可以使用该外设功能。

3. 如果手册中未提及该引脚支持该外设

说明该引脚不支持该功能,即便使用重映射也无法达到目的。

三、JTAG默认占用问题与引脚释放

STM32F103 系列默认启用了全功能 JTAG 调试接口,它会占用多个引脚:

引脚 JTAG功能 PA13 JTMS PA14 JTCK PA15 JTDI PB3 JTDO PB4 JNTRST

如果需要将 PB4 用作其他功能(如 TIM3\\_CH1),必须首先禁用 JTAG 功能,否则该引脚将无法正常输出或输入信号。

禁用 JTAG(保留 SWD)标准库写法如下:

// 开启 AFIO 外设时钟,这是使用重映射的前提RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 禁用 JTAG,仅保留 SWD(两线调试),释放 PB3、PB4、PA15GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

这行代码会释放 PB3、PB4、PA15,使其恢复为普通可配置引脚。

四、重映射类型介绍(无重映射 / 部分重映射 / 完全重映射)

STM32F103 系列在设计时为部分外设功能预设了多种映射方式,主要分为以下三类:

1. 无重映射(No Remap)

使用默认引脚。例如 TIM3\\_CH1 默认映射到 PA6,TIM3\\_CH2 映射到 PA7。

2. 部分重映射(Partial Remap)

将部分通道映射到其他引脚,例如将 TIM3\\_CH1 映射到 PB4TIM3\\_CH2 映射到 PB5

标准库代码:

// 将 TIM3 的 CH1 和 CH2 通道映射到 PB4 和 PB5(部分重映射)GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

3. 完全重映射(Full Remap)

将所有通道映射到全新的引脚组,例如 TIM3 的所有通道映射到 PC6\\~PC9

标准库代码:

// 将 TIM3 所有通道映射到 PC6-PC9(完全重映射)GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

所有重映射配置都可在参考手册(RM0008)第九章 AFIO 章节中查到。

五、实战案例:TIM3PB4/PB5输出PWM控制电机

背景:

在使用 L9110S 电机驱动模块时,需要控制两个引脚(如 PB4 和 PB5)输出 PWM 信号,实现电机的正反转与调速。但 PB4 默认是 JTAG 口的一部分,TIM3 默认也未映射到 PB4/PB5
单片机 - STM32F103“复用功能重映射”完整解析:从JTAG释放到TIM重映射实战详解_gpio复用tim

步骤如下:

1. 释放 PB4 的 JTAG 占用:
// 使能 AFIO 外设的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 禁用 JTAG,仅保留 SWD,释放 PB4 用作普通引脚GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
2. 打开 TIM3 并进行部分重映射:
// 将 TIM3_CH1 和 TIM3_CH2 分别重映射到 PB4 和 PB5GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
3. 配置 GPIO 为复用推挽输出:
GPIO_InitTypeDef GPIO_InitStructure;// 设置为复用推挽输出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;// 设置 IO 输出速度为最大 50MHzGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;// 选择引脚 PB4 和 PB5GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;// 初始化 GPIOB 引脚GPIO_Init(GPIOB, &GPIO_InitStructure);
4. 配置 TIM3 输出 PWM 到 PB4/PB5:
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;// 打开 TIM3 的时钟(APB1总线)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);// 设置 PWM 的频率:PWM_freq = 72MHz / (Prescaler+1) / (Period+1)TIM_TimeBaseStructure.TIM_Period = 999;  // 自动重装载值 ARR:1000 - 1TIM_TimeBaseStructure.TIM_Prescaler = 71; // 分频系数:72MHz / (71+1) = 1MHzTIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟分频因子,通常为0TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);// 配置通道1(PB4)为 PWM 输出TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  // 设置为 PWM 模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能通道输出TIM_OCInitStructure.TIM_Pulse = 500; // 设置占空比为 50%TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 高电平有效TIM_OC1Init(TIM3, &TIM_OCInitStructure);  // 初始化 TIM3 的通道1TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); // 使能预装载// 配置通道2(PB5)为 PWM 输出TIM_OCInitStructure.TIM_Pulse = 500; // 设置占空比TIM_OC2Init(TIM3, &TIM_OCInitStructure);  // 初始化 TIM3 的通道2TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // 使能预装载// 启动 TIM3TIM_Cmd(TIM3, ENABLE);

六、总结与建议

  • STM32F103 的外设引脚不能随意指定,必须遵守 ST 提供的默认映射或预设重映射规则。
  • 若默认引脚被 JTAG 或其他功能占用,应先通过 GPIO_PinRemapConfig 释放。
  • 想要使用非默认引脚的外设功能,必须启用部分或完全重映射。
  • 所有外设的映射组合、支持的重映射模式,都可以在参考手册第九章“AFIO”中查阅。

建议在项目初期就根据引脚分布图和重映射选项合理规划外设引脚,避免开发中途资源冲突。

如需延伸内容(如编码器输入、PWM测频、双路电机控制等),欢迎留言讨论交流。


(完)