单片机 - 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.pswp.cn/bicheng/87027.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】知识总结·内存函数

目录 前言: 一、内存复制函数 1. memcpy - 内存块复制 2. memmove - 内存块移动 二、内存设置函数 1. memset - 内存块填充 三、内存比较函数 1. memcmp 2.memchr 三内存分配函数 1 .malloc 2.free 总结: 注意事项: 前言&…

python+uniapp基于微信小程序面向品牌会员的在线商城系统

文章目录 具体实现截图本项目支持的技术路线源码获取详细视频演示:文章底部获取博主联系方式!!!!本系统开发思路进度安排及各阶段主要任务java类核心代码部分展示主要参考文献:源码获取/详细视频演示 ##项目…

小鱼fish系统 sudo apt update报错(密钥失效)

在使用小鱼fish提供的系统镜像文件,sudo apt update系统更新时遇到了以下报错,即ROS 2 仓库的 GPG 密钥已过期,以及 Docker 仓库使用了过时的密钥存储方式 fishrosfishros-linux:~$ sudo apt update 获取:1 http://mirrors.tuna.tsinghua.ed…

深度优先搜索 (DFS) 详解

1. 什么是深度优先搜索? 深度优先搜索(Depth-First Search, DFS)是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都已被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进…

文心4.5开源大模型的使用和部署

前言 就在今天,文心4.5模型开源了,不是一个,而是整个系列模型正式开源。很突然,我都震惊了。文心4.5系列开源模型共10款,涵盖了激活参数规模分别为47B 和3B 的混合专家(MoE)模型(最…

HarmonyOs开发之——TypeScript介绍、入门,及 TypeScript、JavaScript、ArkTs的具体区别解读。

HarmonyOs开发之——TypeScript介绍、入门,及 TypeScript、JavaScript、ArkTs的具体区别解读。 一、 开发语言介绍: TypeScript是JavaScript的超集,ArkTS则是TypeScript的超集。ArkTs是 HarmonyOs的主力开发语言,它在TypeScript…

《JMS事务性会话彻底解析:消息监听中的 commit、rollback 和幂等设计》

大家好,我是G探险者! 📌 场景引入 在实际项目中,我们常常面临以下挑战: 监听 MQ 消息失败了,希望自动重试?消费 MQ 消息后,要写数据库,但中间报错了?消息处…

vue3 el-table 列增加 自定义排序逻辑

在 Vue 3 中使用 Element Plus 的 <el-table> 组件时&#xff0c;如果你想增加自定义排序逻辑&#xff0c;可以通过以下几个步骤实现&#xff1a; 1. 使用 default-sort 属性 首先&#xff0c;你可以在 <el-table> 组件上使用 default-sort 属性来指定默认的排序…

ISP Pipeline(7): Gamma Correction 伽马校正

AI_Plays/ISP/Fast_ISP_Progress.ipynb at main ameengee/AI_Plays GitHub Gamma Correction&#xff08;伽马校正&#xff09;是图像处理中的一个重要步骤&#xff0c;目的是调整图像的亮度&#xff0c;使其更符合人眼的感知或显示设备的特性。 为什么需要 Gamma Correcti…

AI提取伴奏,实现卡拉OK效果 —— 「suno api/luno api/kuka api」

导读 喜欢唱歌&#xff0c;却总苦于找不到纯净的伴奏&#xff1f;或者你想把喜欢的歌曲翻唱一遍&#xff0c;却被人声干扰搞得头大&#xff1f;现在&#xff0c;AI技术已经悄悄解决了这个问题。借助AI智能工具&#xff0c;你可以轻松提取任何一首歌的伴奏&#xff0c;享受宛如…

pip介绍

pip是什么&#xff1f; pip&#xff08;Pip Installs Packages&#xff09;是Python的官方管理工具&#xff0c;用于安装、升级、卸载和管理Python第三方库及其依赖关系。它是Python生态系统的核心组件&#xff0c;通过连接PyPI&#xff08;Python Package Index&#xff09;这…

机器学习20-线性网络思考

机器学习20-线性网络思考 针对线性网络的基础问题&#xff0c;使用基础示例进行解释 1-核心知识点 1-线性模型家族的线性回归和逻辑回归分别是什么&#xff0c;线性模型家族还有没有其他的模型 线性模型家族是一系列基于线性假设的统计模型&#xff0c;它们假设因变量和自变量…

【科研绘图系列】R语言绘制世界地图分布(world map)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理准备画图画图总结系统信息介绍 本教程旨在通过R语言及其相关地理空间分析包,展示如何对环境数据进行空间聚类分析,并将结果可视化。教程从读…

Armbian 25.5.1 Noble Gnome 开启远程桌面功能

sudo apt install gnome-remote-desktop ----长话短说 故障表现 Ubuntu 25版本点击远程桌面功能没有任何反应, WIN_20250630_00_53_24_Pro 最后 armbian 官方社区充满了傲慢,一言不合就关闭话题,问题都没有解决就给我关闭了 最后检索到英文网站,说到了这么一句话,检查远程桌…

嵌入式 Linux 入门:从裸机到系统级开发的第一步

随着嵌入式系统应用的不断深入&#xff0c;很多 MCU 项目开发者会在某个阶段遇到瓶颈&#xff1a;系统越来越复杂、任务越来越多、通信越来越频繁、性能要求越来越高。 这时候&#xff0c;从 MCU / RTOS 过渡到 嵌入式 Linux 开发 就成为一次技术升级的关键转折点。 本文将带…

详解 Blazor 组件传值

父子组件传值 在 Blazor 中&#xff0c;组件之间的通信可以通过 [Parameter] 参数和 EventCallback<T> 事件回调实现。下面分别给出 父组件传递值给子组件 和 子组件传递值给父组件 的简单示例。 1.1 父组件传递值给子组件 步骤&#xff1a; 在子组件中定义 public 属…

力扣热题100再刷

160.相交链表 读一遍A&#xff0c;一个set存节点&#xff0c;遍历B的时候判断即可。复习下set的STL&#xff1a;set有set和unordered_set&#xff0c;同样有insert&#xff0c;find&#xff0c;count&#xff0c;对于set而言&#xff0c;自动从小到大排序&#xff0c;还有&…

MySQL常用函数性能优化及索引影响分析

MySQL 常用函数性能优化指南&#xff08;含索引影响分析&#xff09; 以下是 MySQL 函数使用指南&#xff0c;新增性能影响评级、索引失效分析和优化方案&#xff0c;帮助您高效使用函数&#xff1a; &#x1f4dc; 一、字符串处理函数&#xff08;含性能分析&#xff09; 函…

莫队(基础版)优雅的暴力

莫队算法是一种离线算法&#xff0c;常用于高效处理区间查询问题。它通过合理排序和移动左右端点来减少时间复杂度。 基本思想 莫队算法的核心思想是将所有查询离线排序&#xff01;&#xff01;&#xff08;找出一个过起来最快的查询顺序&#xff09;&#xff0c;然后通过移动…

✨ Python 高级定制 | 美化 Word 表格边框与样式(收货记录增强版)

之前我们完成了 Excel 数据提取、Word 表格写入与合并&#xff0c;现在继续 为 Word 表格添加高级样式 装扮&#xff0c;包括单元格边框、背景填色、居中对齐、粗体、高亮行/列等&#xff0c;进一步增强表格的可读性与专业性。 &#x1f58c;️ 样式设置函数 1. 设置单元格边框…