当前位置: 首页 > news >正文

单片机 - STM32F103“复用功能重映射”完整解析:从JTAG释放到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功能
PA13JTMS
PA14JTCK
PA15JTDI
PB3JTDO
PB4JNTRST

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

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

// 开启 AFIO 外设时钟,这是使用重映射的前提
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 禁用 JTAG,仅保留 SWD(两线调试),释放 PB3、PB4、PA15
GPIO_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
在这里插入图片描述

步骤如下:

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 和 PB5
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
3. 配置 GPIO 为复用推挽输出:
GPIO_InitTypeDef GPIO_InitStructure;// 设置为复用推挽输出模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// 设置 IO 输出速度为最大 50MHz
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// 选择引脚 PB4 和 PB5
GPIO_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 - 1
TIM_TimeBaseStructure.TIM_Prescaler = 71;         // 分频系数:72MHz / (71+1) = 1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;      // 时钟分频因子,通常为0
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);// 配置通道1(PB4)为 PWM 输出
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;           // 设置为 PWM 模式1
TIM_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 的通道1
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);            // 使能预装载// 配置通道2(PB5)为 PWM 输出
TIM_OCInitStructure.TIM_Pulse = 500;                         // 设置占空比
TIM_OC2Init(TIM3, &TIM_OCInitStructure);                     // 初始化 TIM3 的通道2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);            // 使能预装载// 启动 TIM3
TIM_Cmd(TIM3, ENABLE);

六、总结与建议

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

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

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


(完)

http://www.lqws.cn/news/532891.html

相关文章:

  • CTF:PHP 多关卡绕过挑战
  • 专注推理查询(ARQs):一种提升大型语言模型指令遵循度、决策准确性和防止幻觉的结构化方法
  • 【攻防篇】解决:阿里云docker 容器中自动启动xmrig挖矿
  • ISP Pipeline(5): Auto White Balance Gain Control (AWB) 自动白平衡
  • 数据结构大项目
  • react - ReactRouter—— 路由传参
  • 【STM32 学习笔记】PWR电源控制
  • Java 大视界 -- 基于 Java 的大数据可视化在智慧城市能源消耗动态监测与优化决策中的应用(324)
  • 【linux】全志Tina配置swupdate工具进行分区打包
  • 《PT100两线制温度测量系统设计:从电路原理到嵌入式实现》
  • 【嵌入式ARM汇编基础】-ELF文件格式内部结构详解(二)
  • 香港政府发表《香港数字资产发展政策宣言 2.0》,提出「LEAP」框架
  • 星型模式(Star Schema)
  • lua脚本为什么能保证原子性
  • 云效代码仓库导入自建gitlab中
  • Redis核心知识详解:从全局命令到高级数据结构
  • 首款SUV小米YU7、小米AI眼镜等新品重磅发布,玄戒O1超大规模量产
  • 湖北理元理律师事务所:科学债务优化如何守护民生底线
  • MySQL 总是差八个小时,如何破?
  • Linux中部署Jenkins保姆间教程
  • 爬虫005----Selenium框架
  • 9. 回文数
  • MySQL (二):范式设计
  • Linux服务器部署Leantime与cpolar构建低成本团队协作环境
  • LRU缓存C++
  • kubernetes》》k8s》》滚动发布 、金丝雀发布 、
  • 医疗AI专科子模型联邦集成编程分析
  • 第一章-人工智能概述-机器学习基础与应用(1/36)
  • 时序分析未完待续
  • DeepSeek16-open-webui Pipelines开发填坑