先說為什么會不夠用
一般在項目開發(fā)階段需求都是慢慢的添加的,預計需要18個IO結果20個還不夠,甚至有的時候已經全部用完了現有的資源,還需要多出一個或者兩個IO來做一個系統(tǒng)運行指示燈這樣的功能,就沒必要換一款更高性能的單片機來做了,這時候就會想能不能再“壓榨”一下單片機把多余的資源釋放出來。其實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不夠用應該這么來
先說為什么會不夠用
一般在項目開發(fā)階段需求都是慢慢的添加的,預計需要18個IO結果20個還不夠,甚至有的時候已經全部用完了現有的資源,還需要多出一個或者兩個IO來做一個系統(tǒng)運行指示燈這樣的功能,就沒必要換一款更高性能的單片機來做了,這時候就會想能不能再“壓榨”一下單片機把多余的資源釋放出來。其實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);