你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F1端口复用、端口重映射经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-15 19:07
端口复用功能& ~7 L2 O& ^3 O, J) b$ i
        STM32 有很多的内置外设(比如:串口、ADC、DAC等是独立的模块和内核连接在一起),这些外设的外部引脚都是与 GPIO 复用的。也就是说,一个 GPIO如果可以复用为内置外设的功能引脚,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。/ ]# p& @- O9 ~# A1 V) u0 D- z" e! Z
        大家都知道,MCU 都有串口,STM32 有好几个串口。比如说 STM32F103ZET6 有 5 个串口,我们可以查手册知道,串口 1 的引脚对应的 IO 为 PA9,PA10.PA9,PA10 默认功能是 GPIO,所以当PA9,PA10 引脚作为串口 1 的 TX,RX 引脚使用的时候,那就是端口复用。查看芯片资料可知道那些口是复用端口。+ i; U' s* H! t8 ]$ H+ F

5 [0 a# x& C- {( [; ?

& |; p; T6 n: A* o  e3 N" I复用端口初始化有几个步骤:
, E6 E6 c* k+ ]% L, P& D: t
7 U; c  S& N# {% y# |

( u' J& P, |  c. f; VGPIO 端口时钟使能。要使用到端口复用,当然要使能端口的时钟了。
1 a% k/ q0 q( Q* K3 `+ y8 u3 m' ^
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    9 g% B5 w% |9 _. `. ~8 b
复制代码
. {1 b( `9 `* ~2 \
复用的外设时钟使能。比如你要将端口 PA9,PA10 复用为串口,所以要使能串口时钟。- L. i9 U8 G) K" v
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    ) N% {% a0 b) i( ]# V
复制代码
8 P# u6 Q, ?! g
端口模式配置。 在 IO 复用为内置外设功能引脚的时候,必须设置 GPIO 端口的模式,至于 在复用功能下 GPIO 的模式是怎么对应的,这个可以查看手册《STM32 中文参考手册 V10》 P110 的表格“8.1.11 外设的 GPIO 配置”。这里我们拿 Usart1 举例:3 b) i  u4 C) w# y9 o$ m, B7 J! U

8 ~$ K9 N0 `$ {
% b/ v+ S; w; Z  J
20201204162037509.png 1 c! G- Q2 Q' g3 C) l3 m

/ `9 |& I9 ?% B0 ~+ o: }% T4 E% ~

9 B; U& m1 s2 \1 D" Y" w3 F* v+ s从表格中可以看出,我们要配置全双工的串口 1,那么 TX 管脚需要配置为推挽复用输出,RX 管脚配置为浮空输入或者带上拉输入。
3 w& j* y% T9 A- u" o7 R8 S0 X# h/ ~
0 L  }; X+ h& n4 h- D
代码如下:
" B1 ^* \% H# H0 D7 \& Z$ w2 u
  1. //USART1_TX PA.9 复用推挽输出
    " |& @) F) i# z3 l! @
  2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    ! U# s8 l, u5 x) R+ X8 {& F# E
  3. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    6 s% E: }8 p9 V; o, ^7 X( t
  4. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    1 m/ g9 ~8 l! p4 Q6 H% |( B; D
  5. GPIO_Init(GPIOA, &GPIO_InitStructure);1 i4 A% y. S4 S. X0 Q" c
  6. //USART1_RX PA.10 浮空输入* \* J. `/ `/ [/ t. J/ U
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    + f1 [# ~4 V1 l0 c  j- w% z+ F
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入; B% M  J5 a% S/ B' Y. R
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);
    # c: t: G, t0 t5 }3 Y0 C2 d$ o
复制代码
9 b/ |4 I" F& W9 _6 Y
我们在使用复用功能的是时候,最少要使能 2 个时钟:/ v# Y+ j9 R" L/ |. N$ C
GPIO 时钟使能
7 f) Q5 s2 y( i9 z6 }7 z+ q复用的外设时钟使能同时要初始化 GPIO 以及复用外设功能
3 _( c8 s8 j9 m& u% ~$ R( S% A; y! I3 Z( U% \, w
% [: |, g- \5 |1 I1 }: Q
端口重映射1 u1 w* c9 L% X7 G
        为了使不同器件封装的外设 IO 功能数量达到最优,可以把一些复用功能重新映射到其他一些引脚上。STM32 中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 STM32 中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。! O8 ^9 y$ [. \4 n8 T/ l2 M1 b
        简单的讲就是把管脚的外设功能映射到另一个管脚,但不是可以随便映射的,具体对应关系《STM32 中文参考手册 V10》的 P116 页“8.3 复用功能和调试配置”有讲解。这里我们同样拿串口 1 为例来讲解。
3 ?$ F6 v& {) m- @% a4 `) e3 ~: C. u

. u7 T5 A% n! i9 G7 |$ @1 Q" ? 20201204163136329.png : T0 L/ }8 S: m/ b- A

. t$ A8 {" W" M  R( X" w0 D
" `* G  i( ^0 w! y7 @8 K; ]9 L
        上图是截取的中文参考手册中的重映射表,从表中可以看出,默认情况下,串口 1 复用的时候的引脚位 PA9,PA10,同时我们可以将 TX 和 RX 重新映射到管脚 PB6 和 PB7 上面去。
# r5 W) g( Y' ^0 R" v8 F" r& l        所以重映射我们同样要使能复用功能的时候讲解的 2 个时钟外,还要使能 AFIO 功能时钟,然后要调用重映射函数。详细步骤为:1 n7 P1 j8 z% z4 \1 w0 T- t# i
& o; c3 N' R$ V
% e% a$ t! H1 z
使能 GPIOB 时钟:/ M% e" y2 ~$ w  ^. o( F
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);. E, {0 t- v0 j
复制代码

4 K2 u/ G, l! z$ U使能串口 1 时钟:
1 P. I' Y! z6 E+ |
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    , z0 P, v) o7 ?6 r" \% F3 j1 S
复制代码

5 o: i; D( x8 `' O9 F, G7 W使能 AFIO 时钟:. m( _: ]$ y8 S' m6 U
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    & m, F+ J; L9 Q" g
复制代码
6 @% P6 P0 Y" z2 z/ o* E
PS: 在对寄存器AFIO_MARR,AFIO_EXTICRX和AFIO_EVCP进行读写操作前,应首先打开AFIO时钟。
" T7 p3 u. R; W1、 AFIO_MARR:配置复用功能映射0 W9 k# N! R3 Z4 d- O8 `6 b' n& M
2、 AFIO_EXTICRX:配置外部中断线映射
  y0 y1 V' S' Y3 @: {3、 AFIO_EVCP:配置EVENTOUT事件输出' b9 p$ o/ h& r! A9 _1 l/ W
4 g+ v- s4 c5 Q5 P% [" J
. G4 p; x& a% R, ~  ~" C3 x
开启重映射:/ l/ ?. r2 f) a& y
  1. GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
    % B- g: V" S  B. U5 l
复制代码
( H4 e7 N. y8 ~& q. I" J& S
这样就将串口的 TX 和 RX 重映射到管脚 PB6 和 PB7 上面了。至于有哪些功能可以重映射,大家除了查看中文参考手册之外,还可以从 GPIO_PinRemapConfig 函数入手查看第一个入口参数的取值范围可以得知。在stm32f10x_gpio.h 文件中定义了取值范围为下面宏定义的标识符,这里我们贴一小部分:1 [6 u! k$ B# ]+ {7 p2 u" u  [" v
  1. #define GPIO_Remap_SPI1 ((uint32_t)0x00000001)
    8 ~* d* o6 q4 y+ l# v1 V; v4 W
  2. #define GPIO_Remap_I2C1 ((uint32_t)0x00000002)
    : q- o! A' n) n; Q3 ?; T
  3. #define GPIO_Remap_USART1 ((uint32_t)0x00000004) * b/ ~) ?( e% ~. p+ ^
  4. #define GPIO_Remap_USART2 ((uint32_t)0x00000008)
    4 d( n9 n6 n0 j9 V5 g% @* K8 g
  5. #define GPIO_PartialRemap_USART3 ((uint32_t)0x00140010)
    " r; m) K- c$ s  w6 r# u8 W: ?* }7 I
  6. #define GPIO_FullRemap_USART3 ((uint32_t)0x00140030)! e0 r0 F# W) H: F) P
复制代码

, |( }- n8 Q7 p: C从上面可以看出,USART1 只有一种重映射,而对于 USART3,存在部分重映射和完全重映射。所谓部分重映射就是部分管脚和默认的是一样的,而部分管脚是重新映射到其他管脚。而完全重映射就是所有管脚都重新映射到其他管脚。看看手册中的 USART3 重映射表:
( d& D4 p8 ]% q
+ L( F. x& G+ e  w) H5 r9 H& r

! X+ ^2 c; ^- q 20201204173139398.png
. l" B' n" ^% v9 s& ^
- ]+ C8 O; \7 ?. b6 R1 L5 t* W
1 }$ j5 a6 q0 `* U! N: a' ~. d5 F( t
部分重映射就是 PB10,PB11,PB12 重映射到 PC10,PC11,PC12 上。而 PB13 和 PB14 和没有重映射情况是一样的,都是 USART3_CTS 和 USART3_RTS 对应管脚。完全重映射就是将这两个脚重新映射到 PD11 和 PD12 上去。我们要使用 USART3 的部分重映射,我们调用函数方法为:
2 U9 [% s# Q- i! K* N8 I- `# J8 F
  1. GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);: N( S, W+ a- Z/ ^# p% u
复制代码
  x* V- V2 r1 \0 y7 B
————————————————. Y: f. M  j$ d$ A, y5 `3 U, K
版权声明:FHNCSDN
. A- k) r& s% e4 f1 q, g如有侵权请联系删除
# S3 q  A* V7 C* K) H/ O, p1 N! B3 {( p) x# X# c0 v# p( ~+ F

) M" L* g1 M" S. C( A* q
收藏 评论0 发布时间:2023-5-15 19:07

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版