先说为什么会不够用
一般在项目开发阶段需求都是慢慢的添加的,预计需要18个IO结果20个还不够,甚至有的时候已经全部用完了现有的资源,还需要多出一个或者两个IO来做一个系统运行指示灯这样的功能,就没必要换一款更高性能的单片机来做了,这时候就会想能不能再“压榨”一下单片机把多余的资源释放出来。其实STM32F103单片机JTAG端口重映射可以完成这样的事情。
STM32F103单片机JTAG端口重映射
JTAG接口
简单理解这是一个下载程序用的接口使用的工具是Jlink
SWD接口
简单理解就是一个下载程序的接口使用的工具是STlink
IO口
简单理解就是一个可以进行输入输出的普通接口
STM32的IO口
STM32有很多IO口,IO口占据了绝大多数的管脚,但是有的管脚天生就不平凡被安排了更牛逼的工作那就是下载程序用,如果想要它由牛逼变成普通就要对本事下载接口的管脚进行功能重新映射。
映射的关系由寄存器进行控制也可以库函数来实现,但是映射的方式不多,也就三种
§全功能 SWJ,JTAG没有JTRST。
§禁用JTAG,启用SWJ。(PB3/PB4/PA15 可重映射为其他功能)
§完全禁用 SWJ和 JTAG。(PB3/PB4/PA13/PA14/PA15 均可重映射为其他功能)
§为什么要这样搞?
因为这样设计可以允许更多的GPIO被解放出来。
比如
第一种可以解放PB4
第二种可以解放PB3 PB4 PA15
第三种可以解放PB3 PB4 PA13 PA14 PA15
为什么可以这样搞?
如何解放对应的IO呢?
STM32F103单片机IO不够用应该这么来
先说为什么会不够用
一般在项目开发阶段需求都是慢慢的添加的,预计需要18个IO结果20个还不够,甚至有的时候已经全部用完了现有的资源,还需要多出一个或者两个IO来做一个系统运行指示灯这样的功能,就没必要换一款更高性能的单片机来做了,这时候就会想能不能再“压榨”一下单片机把多余的资源释放出来。其实STM32F103单片机JTAG端口重映射可以完成这样的事情。
STM32F103单片机JTAG端口重映射
JTAG接口
简单理解这是一个下载程序用的接口使用的工具是Jlink
SWD接口
简单理解就是一个下载程序的接口使用的工具是STlink
IO口
简单理解就是一个可以进行输入输出的普通接口
STM32的IO口
STM32有很多IO口,IO口占据了绝大多数的管脚,但是有的管脚天生就不平凡被安排了更牛逼的工作那就是下载程序用,如果想要它由牛逼变成普通就要对本事下载接口的管脚进行功能重新映射。
映射的关系由寄存器进行控制也可以库函数来实现,但是映射的方式不多,也就三种
§
全功能 SWJ,JTAG没有JTRST。
§
§
禁用JTAG,启用SWJ。(PB3/PB4/PA15 可重映射为其他功能)
§
§
完全禁用 SWJ和 JTAG。(PB3/PB4/PA13/PA14/PA15 均可重映射为其他功能)
§
§
为什么要这样搞?
因为这样设计可以允许更多的GPIO被解放出来。
比如
第一种可以解放PB4
第二种可以解放PB3 PB4 PA15
第三种可以解放PB3 PB4 PA13 PA14 PA15
为什么可以这样搞?
如何解放对应的IO呢?
进行端口复用
·
·
·
·
·
·
·
·
·
·
·
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x4 << 24); //2、关闭JTAG-DP,关闭SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x2 << 24) ; //2、关闭JTAG-DP,开启SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x1 << 24) ; //2、JTAG-DP + SW-DP NOJNRST
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x0 << 24) ; //2、都被占用
库函数写法
·
·
·
·
·
·
·
·
·
·
·
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x4 << 24); //2、关闭JTAG-DP,关闭SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x2 << 24) ; //2、关闭JTAG-DP,开启SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x1 << 24) ; //2、JTAG-DP + SW-DP NOJNRST
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x0 << 24) ; //2、都被占用
库函数写法
·
·
·
·
·
·
·
·
·
·
·
·
·
·
//开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //Full SWJ Disabled (JTAG-DP + SW-DP)GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
//开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//JTAG-DP Disabled and *SW-DP Enabled*GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRSTGPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE);
·
·
·
·
·
·
·
·
·
·
·
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x4 << 24); //2、关闭JTAG-DP,关闭SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x2 << 24) ; //2、关闭JTAG-DP,开启SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x1 << 24) ; //2、JTAG-DP + SW-DP NOJNRST
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x0 << 24) ; //2、都被占用
库函数写法
·
·
·
·
·
·
·
·
·
·
·
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x4 << 24); //2、关闭JTAG-DP,关闭SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x2 << 24) ; //2、关闭JTAG-DP,开启SW-DP
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x1 << 24) ; //2、JTAG-DP + SW-DP NOJNRST
AFIO -> MAPR &= ~(0x7 << 24); //1、清除[26 : 24]AFIO -> MAPR |= (0x0 << 24) ; //2、都被占用
库函数写法
·
·
·
·
·
·
·
·
·
·
·
·
·
·
//开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //Full SWJ Disabled (JTAG-DP + SW-DP)GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
//开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//JTAG-DP Disabled and *SW-DP Enabled*GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRSTGPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE);