STM32单片机复位后,JTAG口默认是被占用的。如果想将JTAG占用的几个IO口设置为普通IO口,就需要进行端口重映射。
- C) y$ _4 b& ~& ]+ ~
6 `) h' A7 h; a复位后端口默认功能可以在STM32参考手册上看到
" M* s# a P2 _+ J1 {! J; Y. j$ y3 _: R) L- x6 B3 L
* B2 N3 G$ ]( L2 Z4 V
- `. ]+ F* x6 X4 H, X- S l4 `, q9 ]要将JTAG占用的这些口设置为普通IO口时,需要用复用功能重映射,在程序开始执行时将JTAG口重映射为普通IO口。
, U' ~' s" W: _
& \5 r5 }& R2 F g; W7 C- P
\6 N8 G/ z* Y/ U2 q
! D6 K8 j( w1 z9 B. {3 l# [
# l1 r/ G2 }. g( V) A将JTAG要设置为普通 IO口时,需要设置AFIO_MAPR寄存器的SWJ_CFG位。如果用寄存器操作的话,就直接设置这个寄存器的值就行。如果用库函数操作的话,可以直接调用库函数void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)。
, |- U' g+ Z+ i; [2 F: Q. T( U. f+ d8 ^- u% G ~
这个库函数的具体实现可以在stm32f10x_gpio.c这个文件中查看,具体代码如下:
+ X0 d0 o8 {* c, L' M; Y) X/ ?$ h+ B3 V- t/ V
- /**
0 R; l- D; z8 C& O. g1 z1 e - * @brief Changes the mapping of the specified pin.
. }$ ~6 M, q. e+ T4 y, q - * @param GPIO_Remap: selects the pin to remap.5 p ^7 ]( q1 {( k
- * This parameter can be one of the following values:/ t0 `: h" `8 J2 x: O% S
- * @arg GPIO_Remap_SPI1 : SPI1 Alternate Function mapping
8 }- _+ ~: B/ ~1 H! _ - * @arg GPIO_Remap_I2C1 : I2C1 Alternate Function mapping C% y8 F) O* v6 K8 {% B2 |
- * @arg GPIO_Remap_USART1 : USART1 Alternate Function mapping% B! a- E' [# U: ]: U# }
- * @arg GPIO_Remap_USART2 : USART2 Alternate Function mapping' B% T6 L3 p8 d; ~1 X% Z
- * @arg GPIO_PartialRemap_USART3 : USART3 Partial Alternate Function mapping
2 c# G( p! V" D; B0 i4 H - * @arg GPIO_FullRemap_USART3 : USART3 Full Alternate Function mapping
2 U2 Q: R P" c& L - * @arg GPIO_PartialRemap_TIM1 : TIM1 Partial Alternate Function mapping
1 ^/ E9 X# }3 F* v+ M( q - * @arg GPIO_FullRemap_TIM1 : TIM1 Full Alternate Function mapping. Q8 @0 B2 k% V( E; _) B4 G
- * @arg GPIO_PartialRemap1_TIM2 : TIM2 Partial1 Alternate Function mapping
) W* [: J5 j# Z. }# _) R* `9 V3 N - * @arg GPIO_PartialRemap2_TIM2 : TIM2 Partial2 Alternate Function mapping$ W, L5 b: E: |$ J8 _
- * @arg GPIO_FullRemap_TIM2 : TIM2 Full Alternate Function mapping
( e$ U! r' K/ i( q2 U - * @arg GPIO_PartialRemap_TIM3 : TIM3 Partial Alternate Function mapping
7 O: [: O0 e( Y% e - * @arg GPIO_FullRemap_TIM3 : TIM3 Full Alternate Function mapping3 ?' x6 }2 }7 u! u# ]
- * @arg GPIO_Remap_TIM4 : TIM4 Alternate Function mapping
: i; `5 a1 e+ [. b5 K: P9 I! f! c - * @arg GPIO_Remap1_CAN1 : CAN1 Alternate Function mapping5 Z5 Z) j4 n* @+ g+ T
- * @arg GPIO_Remap2_CAN1 : CAN1 Alternate Function mapping. L% ~. \& e! C5 r# G* l$ N
- * @arg GPIO_Remap_PD01 : PD01 Alternate Function mapping
( ~" x/ ?" ~% a4 b6 p - * @arg GPIO_Remap_TIM5CH4_LSI : LSI connected to TIM5 Channel4 input capture for calibration' r$ e: w" b* L/ E6 ?6 V; }
- * @arg GPIO_Remap_ADC1_ETRGINJ : ADC1 External Trigger Injected Conversion remapping& k- k) Z( a8 Q6 p
- * @arg GPIO_Remap_ADC1_ETRGREG : ADC1 External Trigger Regular Conversion remapping8 m8 L& J& n p/ H# [7 i5 a
- * @arg GPIO_Remap_ADC2_ETRGINJ : ADC2 External Trigger Injected Conversion remapping
5 E2 ^1 ^+ F F' s. o - * @arg GPIO_Remap_ADC2_ETRGREG : ADC2 External Trigger Regular Conversion remapping
2 e* ^/ F3 U3 j' O- ~2 ~3 r* a+ ?. V - * @arg GPIO_Remap_ETH : Ethernet remapping (only for Connectivity line devices)0 Z& W2 N0 T8 J/ \
- * @arg GPIO_Remap_CAN2 : CAN2 remapping (only for Connectivity line devices). V5 F- `0 M6 g* h: R* L$ G8 B, i
- * @arg GPIO_Remap_SWJ_NoJTRST : Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST# u8 s7 O& {0 @" E# Q) P! Q/ D: }0 Z0 o; v
- * @arg GPIO_Remap_SWJ_JTAGDisable : JTAG-DP Disabled and SW-DP Enabled
& `3 @% w$ H* {& I. `# ]; w! ` - * @arg GPIO_Remap_SWJ_Disable : Full SWJ Disabled (JTAG-DP + SW-DP)
" C8 U' g4 x$ Z& }4 @0 U U - * @arg GPIO_Remap_SPI3 : SPI3/I2S3 Alternate Function mapping (only for Connectivity line devices)
2 D u$ V" W4 p# K! J - * When the SPI3/I2S3 is remapped using this function, the SWJ is configured. x$ n" Y/ i8 z" V! O
- * to Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST.
( N9 S& h; q, V) J/ h - * @arg GPIO_Remap_TIM2ITR1_PTP_SOF : Ethernet PTP output or USB OTG SOF (Start of Frame) connected ]- |3 a% l4 j" y7 s
- * to TIM2 Internal Trigger 1 for calibration (only for Connectivity line devices)
3 F/ P; J1 L$ x2 R - * If the GPIO_Remap_TIM2ITR1_PTP_SOF is enabled the TIM2 ITR1 is connected to / e$ D4 L9 }6 g* E- D7 M
- * Ethernet PTP output. When Reset TIM2 ITR1 is connected to USB OTG SOF output. - i8 X$ D) D/ I- C" n0 p: A
- * @arg GPIO_Remap_PTP_PPS : Ethernet MAC PPS_PTS output on PB05 (only for Connectivity line devices)3 A7 }& @1 G0 K }1 h2 L5 A
- * @arg GPIO_Remap_TIM15 : TIM15 Alternate Function mapping (only for Value line devices). O5 _2 K" m6 R- S1 Z' e) ^
- * @arg GPIO_Remap_TIM16 : TIM16 Alternate Function mapping (only for Value line devices)
4 E2 h8 o# j, r: R" f. \( Z* ] - * @arg GPIO_Remap_TIM17 : TIM17 Alternate Function mapping (only for Value line devices)* ~8 z- ]7 j8 s
- * @arg GPIO_Remap_CEC : CEC Alternate Function mapping (only for Value line devices)
# F* d. X' c0 o% F - * @arg GPIO_Remap_TIM1_DMA : TIM1 DMA requests mapping (only for Value line devices)
: W7 a& S4 z' j, W" z: `) s* A - * @arg GPIO_Remap_TIM9 : TIM9 Alternate Function mapping (only for XL-density devices)6 j; J1 c& c5 P" J9 v! z. G
- * @arg GPIO_Remap_TIM10 : TIM10 Alternate Function mapping (only for XL-density devices) x A( L% R$ j7 `
- * @arg GPIO_Remap_TIM11 : TIM11 Alternate Function mapping (only for XL-density devices)
& ~9 r0 [2 N. T1 W& `) R" X& T - * @arg GPIO_Remap_TIM13 : TIM13 Alternate Function mapping (only for High density Value line and XL-density devices) ~* f2 q: {- T3 ~
- * @arg GPIO_Remap_TIM14 : TIM14 Alternate Function mapping (only for High density Value line and XL-density devices)
- i4 }. S8 D- f" r- x - * @arg GPIO_Remap_FSMC_NADV : FSMC_NADV Alternate Function mapping (only for High density Value line and XL-density devices)
3 q) C3 [/ M: }0 [ - * @arg GPIO_Remap_TIM67_DAC_DMA : TIM6/TIM7 and DAC DMA requests remapping (only for High density Value line devices)7 T w& o1 z) E/ S( D& i: A! W
- * @arg GPIO_Remap_TIM12 : TIM12 Alternate Function mapping (only for High density Value line devices)7 r4 ~9 O1 `6 d* H' i# h
- * @arg GPIO_Remap_MISC : Miscellaneous Remap (DMA2 Channel5 Position and DAC Trigger remapping,
: ]: G/ C% f7 S$ P, C5 t, a - * only for High density Value line devices)
9 Q) E- u# C1 @) U1 ^ - * @param NewState: new state of the port pin remapping.
6 {& q8 g1 p) W+ ~0 |9 [6 H - * This parameter can be: ENABLE or DISABLE./ i Q# ], i5 {, [. H+ |4 w
- * @retval None
% f" i3 k8 ~9 J- x. b - */
: q2 d! S: @% H9 o - void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)9 U1 ]2 P h: c
- {) K/ B) h0 H3 Y9 Y" L1 D, G- ]
- uint32_t tmp = 0x00, tmp1 = 0x00, tmpreg = 0x00, tmpmask = 0x00;5 T) r1 U0 I. b) F: ~, D9 b2 I0 v, n3 _
( T# Y3 y: _, j* ^8 `# K/ v- /* Check the parameters */7 N% j/ z! U4 v1 q2 O4 U
- assert_param(IS_GPIO_REMAP(GPIO_Remap)); j2 k* P8 [0 q4 v- A
- assert_param(IS_FUNCTIONAL_STATE(NewState));
/ Q+ }8 N7 `% n8 J0 n; j - 8 F7 ^# Q# a5 q5 f
- if((GPIO_Remap & 0x80000000) == 0x80000000), P4 o3 M- Z+ ]2 P! }3 N, N3 Z
- {5 m! F1 ?4 R6 m8 ?1 }
- tmpreg = AFIO->MAPR2;7 r1 e! ^7 `/ v T/ B
- }1 p/ y" J" m R9 h0 R1 Y4 A
- else0 n* p( D- k2 \: w& ` t" V
- {
3 _. e9 [( z) I6 T! K8 ` - tmpreg = AFIO->MAPR;
/ t3 O6 r0 R1 ?2 e6 o - }
# u- f" |- F# l8 W - 8 Q/ O, \" p! i' f+ C7 t
- tmpmask = (GPIO_Remap & DBGAFR_POSITION_MASK) >> 0x10;
, b5 w' u8 C7 a1 \ - tmp = GPIO_Remap & LSB_MASK;
, D. S, i, B/ L; ~5 \ - ' I# c4 ~5 ]& Q0 f
- if ((GPIO_Remap & (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) == (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK))6 o- h) a* U& M
- {/ a% j/ n: _- g1 U# [5 l) c6 E
- tmpreg &= DBGAFR_SWJCFG_MASK;
% E* ]3 e c& i$ g f - AFIO->MAPR &= DBGAFR_SWJCFG_MASK;( z2 |3 b4 h1 |
- }
; Z( Q" ^" i' y, [7 a - else if ((GPIO_Remap & DBGAFR_NUMBITS_MASK) == DBGAFR_NUMBITS_MASK)
* }) \" s4 k, D - {& v1 w, |3 Y1 t9 S6 y. O
- tmp1 = ((uint32_t)0x03) << tmpmask;
7 a" j' s' q! u! w* P, s - tmpreg &= ~tmp1;* I3 q/ y$ w9 _' Q
- tmpreg |= ~DBGAFR_SWJCFG_MASK;# e0 ~. S" G: ^' L+ V% j1 s
- }0 \3 G5 l: l. S9 V8 e9 d3 l" S& H) D
- else
$ F+ D3 V1 {5 W - {
9 H4 Q; m1 Y, R4 @; L" G- M - tmpreg &= ~(tmp << ((GPIO_Remap >> 0x15)*0x10));. F6 A) N% s1 ^3 p
- tmpreg |= ~DBGAFR_SWJCFG_MASK;9 W P7 |+ L" ]5 p5 b3 p$ F
- }
# |8 q4 P, \+ Z$ Q3 L
1 ^5 h2 }8 `4 z$ O# u- if (NewState != DISABLE)4 |3 f; E" \7 j
- {% ^+ z& p9 X6 D
- tmpreg |= (tmp << ((GPIO_Remap >> 0x15)*0x10));# z. I+ N/ W% c2 T9 l# D* [
- }. p/ M4 m/ K1 R+ p. X9 I
) N5 i" r s- L0 h1 I" p- if((GPIO_Remap & 0x80000000) == 0x80000000)4 O3 l" n+ I& u' p' g6 y
- {' ^/ Q2 K" [7 j( ^$ H- I7 `/ P/ o- T
- AFIO->MAPR2 = tmpreg;
) M9 j! x$ Q7 j6 h - }
( }- X& A! F' e% c) a - else4 B! m( J* c2 @
- {7 {0 w+ q# `; [
- AFIO->MAPR = tmpreg;
7 s" Z* g# w: t/ s+ u' \* T" f - } 1 O$ w, x6 a$ M
- }
复制代码
3 z7 K" H! y* D& l重映射JTAG口的相关设置只有三个。
: m( f( l2 X9 Y3 H1 i! s- S; R0 V2 N% @7 v$ q5 e$ x
. c) W; l; F6 w0 k0 e! g
2 M5 |8 I. J6 _, }" S+ T& m
通过后面的注释可以知道 / w2 s" b% h- ?' N& k
! V5 i- q6 _2 _, mGPIO_Remap_SWJ_NoJTRST 是使能JTAG和SW功能,但是不包括JTRST引脚。8 ]$ V) C5 a* P$ \
7 c0 f8 h2 y+ s' z, b2 g- HGPIO_Remap_SWJ_JTAGDisable 是禁止JTAG功能,使能SW功能。! S C, E" F: l# t
) y: m, X3 s' x- h& D
GPIO_Remap_SWJ_Disable 是禁止JTAG功能、禁止SW功能。7 G# O. t: @0 O3 J9 I
4 f" j, K. L2 r5 I/ w- b
在设置的时候要注意,如果选中了GPIO_Remap_SWJ_Disable ,那么单片机就不能通过J-link烧写程序了。烧写程序只能通过串口用 ISP 方式进行下载。
! D' v$ x. n% r5 a
5 e2 }/ g4 o# v; ^2 ]通过库函数将JTAG口重映射为普通IO口代码如下:) a- k9 ]2 R8 N( y
: j# I7 X/ Q! X
- GPIO_InitTypeDef GPIO_InitStructure;2 R1 V1 Z- c, ^6 H$ \
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE ); //使能PA、PB端口时钟- M# a1 P I' @# j+ w
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE ); //使能复用功能时钟
5 C2 X! m8 u* t x# R) n; I& K3 p0 G - 9 f: I& |9 {6 S; u
- //将JTAG端口设置为普通IO口
# r6 i5 k0 h5 W7 d3 p+ r8 Q+ I - GPIO_PinRemapConfig( GPIO_Remap_SWJ_JTAGDisable, ENABLE ); // JTAG-DP Disabled and SW-DP Enabled( W/ E0 k" u( `: f/ d! R
- 8 A: o: P0 d% K: N. L- q
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_15;# S& ?( z6 P7 Y) V% f/ _7 @. M
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;, l1 e | o4 p; q' J
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
: E1 W4 V# b3 p- K - GPIO_Init( GPIOB, &GPIO_InitStructure );
4 y! b# Z; ~3 c: F - 2 G( s1 f' F3 j% {# k( E6 [
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_15 | GPIO_Pin_11 | GPIO_Pin_8;
/ C3 y5 E/ U0 D - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
1 d. Q5 Q* J) c; y* m) |& e - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
) |0 ~3 x8 x% w" x/ ` - GPIO_Init( GPIOA, &GPIO_InitStructure );
复制代码 ( C& k) |8 S& r& A9 _- ^
在使用复用功能重映射时,要开启AFIO时钟,否则端口重映射功能开启就会失败。
. v: S2 h1 |& h% n* e: Z2 \4 y, x; O6 H* z( V! h
- [# ?5 Z, L9 e7 \" D+ j" [: |
9 O0 Q+ a% J n |