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

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

[复制链接]
攻城狮Melo 发布时间:2023-5-15 19:07
端口复用功能
* ~7 ?2 [# k0 y        STM32 有很多的内置外设(比如:串口、ADC、DAC等是独立的模块和内核连接在一起),这些外设的外部引脚都是与 GPIO 复用的。也就是说,一个 GPIO如果可以复用为内置外设的功能引脚,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。! Z8 @9 c8 A& |$ Z" v9 k' u6 c1 b/ ]
        大家都知道,MCU 都有串口,STM32 有好几个串口。比如说 STM32F103ZET6 有 5 个串口,我们可以查手册知道,串口 1 的引脚对应的 IO 为 PA9,PA10.PA9,PA10 默认功能是 GPIO,所以当PA9,PA10 引脚作为串口 1 的 TX,RX 引脚使用的时候,那就是端口复用。查看芯片资料可知道那些口是复用端口。" ?8 a2 d' J0 }9 s# e0 s2 D, O4 J

  y4 r+ w$ D9 D' c# E+ d
4 S3 Q+ s' i# c& ^, r
复用端口初始化有几个步骤:8 Z+ t6 r- D2 L" n! ?
8 i8 g* u/ x1 d: k$ _
+ s) m1 w" N+ c0 n8 \; W
GPIO 端口时钟使能。要使用到端口复用,当然要使能端口的时钟了。/ S& V5 n9 h+ ]5 }& L
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);: c. F! I2 A9 W4 m% Q! R
复制代码

& `& j* S1 U, M* u# i复用的外设时钟使能。比如你要将端口 PA9,PA10 复用为串口,所以要使能串口时钟。
  {5 }% }, g7 r% ]8 M
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    ' j* s% z; w' y3 E9 B' j
复制代码
, m- s% C( F* b9 s( \- R: x( E) |
端口模式配置。 在 IO 复用为内置外设功能引脚的时候,必须设置 GPIO 端口的模式,至于 在复用功能下 GPIO 的模式是怎么对应的,这个可以查看手册《STM32 中文参考手册 V10》 P110 的表格“8.1.11 外设的 GPIO 配置”。这里我们拿 Usart1 举例:  B+ c- `6 N$ r  y' P' _$ @; ]
5 t0 J1 [5 S4 I
1 x9 _& E+ L# g3 O, U
20201204162037509.png   |2 a: S) h& `9 M. ]+ m. P- p
$ E6 v- t* g( x6 E9 [" [
; a$ v) D  u; h' @6 U/ }
从表格中可以看出,我们要配置全双工的串口 1,那么 TX 管脚需要配置为推挽复用输出,RX 管脚配置为浮空输入或者带上拉输入。' X. r( ?3 l' \- [( z

- B$ \  _2 a4 I, b  _

, B; P; ^2 [/ Y5 H$ \代码如下:
9 M; l( g; }  X6 x
  1. //USART1_TX PA.9 复用推挽输出
    5 ~6 w) X* K3 J/ E# I) W
  2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    # ^6 {; Z4 T! d% [' @, J6 v
  3. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ) ?8 \& }& R. K+ x
  4. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    + m. N) K0 j! T
  5. GPIO_Init(GPIOA, &GPIO_InitStructure);
    $ z! Y) r  n  H7 p% {7 \
  6. //USART1_RX PA.10 浮空输入2 [/ o* l. {1 Y3 n% N# Q
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    ( t$ s! u& x9 {5 m/ j
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入. Z' S3 p- f4 Y, _1 w- d8 j
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);+ L" n) v' c% {8 L2 d: J
复制代码
3 L# V! L1 w, `. I
我们在使用复用功能的是时候,最少要使能 2 个时钟:
6 a$ |, Y, L- B2 u) B2 p4 MGPIO 时钟使能
; o3 h, N: U+ j3 x+ H复用的外设时钟使能同时要初始化 GPIO 以及复用外设功能" [8 p; w+ m& u6 \/ N( U

- L: O3 ]% p8 T, a# X% G2 ?
0 P: y! @9 [  r' N! t$ C# n
端口重映射2 O: t, l3 r6 k' \0 L5 |# H# I9 l
        为了使不同器件封装的外设 IO 功能数量达到最优,可以把一些复用功能重新映射到其他一些引脚上。STM32 中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 STM32 中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。
- ?' \; A; V+ I' A        简单的讲就是把管脚的外设功能映射到另一个管脚,但不是可以随便映射的,具体对应关系《STM32 中文参考手册 V10》的 P116 页“8.3 复用功能和调试配置”有讲解。这里我们同样拿串口 1 为例来讲解。" Y* v( R5 X5 ^: y+ a: F: s
4 M! S. _+ A  }9 Y) ~6 O  j
5 Q3 Q$ Z# ^/ N+ S
20201204163136329.png
! K+ }! U; `0 K0 @- @7 f5 K; O. P% I5 Y$ J6 W6 p& d- N

4 F! }' N# Q5 |9 g        上图是截取的中文参考手册中的重映射表,从表中可以看出,默认情况下,串口 1 复用的时候的引脚位 PA9,PA10,同时我们可以将 TX 和 RX 重新映射到管脚 PB6 和 PB7 上面去。
- \  k" Z2 E7 Q! }, Q3 J) s( y- p: o        所以重映射我们同样要使能复用功能的时候讲解的 2 个时钟外,还要使能 AFIO 功能时钟,然后要调用重映射函数。详细步骤为:
# m3 x9 {' T: {& Z, W
6 b9 E9 e8 L% E+ ?
! h: Y- c, k; B% S' Q% J- k! |5 a
使能 GPIOB 时钟:
  k3 q. T+ y- H$ M, i8 y
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    6 M4 M0 u5 T% o5 P9 \; i+ [
复制代码
1 j8 B# N8 y. k+ l2 y
使能串口 1 时钟:
2 `( ]+ T5 N/ ]# t3 R! Q! e  d
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    " P+ t$ r3 c: P
复制代码

0 Q7 c: H/ W2 x1 L  j9 D5 X使能 AFIO 时钟:
' ?/ C' K* H0 N0 X: d; Z
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);; C; [0 i. G# Z  C5 u
复制代码
* _$ M) V2 b6 L
PS: 在对寄存器AFIO_MARR,AFIO_EXTICRX和AFIO_EVCP进行读写操作前,应首先打开AFIO时钟。- c2 h8 r- p  k5 p
1、 AFIO_MARR:配置复用功能映射" y' t% w- d. |+ I# R: E' C
2、 AFIO_EXTICRX:配置外部中断线映射* T0 W5 l+ z7 Z2 _5 I/ F/ y/ k/ [
3、 AFIO_EVCP:配置EVENTOUT事件输出4 B- `3 O7 C  a5 P0 ?

2 P9 \2 i1 N1 M
( n( f3 n. y4 s- F2 }8 a5 W
开启重映射:
: Q& x0 _3 h  U+ R$ u
  1. GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);5 {, W  a! U& V4 z$ Y
复制代码

6 e. b, Q6 i. J4 ^. |这样就将串口的 TX 和 RX 重映射到管脚 PB6 和 PB7 上面了。至于有哪些功能可以重映射,大家除了查看中文参考手册之外,还可以从 GPIO_PinRemapConfig 函数入手查看第一个入口参数的取值范围可以得知。在stm32f10x_gpio.h 文件中定义了取值范围为下面宏定义的标识符,这里我们贴一小部分:$ w' z7 ^( V4 p
  1. #define GPIO_Remap_SPI1 ((uint32_t)0x00000001)
    ( N& y( S: M$ {2 l$ U9 {$ z8 e$ C
  2. #define GPIO_Remap_I2C1 ((uint32_t)0x00000002)
    3 X& D) D# |- a# X
  3. #define GPIO_Remap_USART1 ((uint32_t)0x00000004) 8 y$ @1 d3 r/ R/ R& Y* b
  4. #define GPIO_Remap_USART2 ((uint32_t)0x00000008)
    * o/ i$ e! P, g; @0 a, @
  5. #define GPIO_PartialRemap_USART3 ((uint32_t)0x00140010)
    8 ^4 F$ Q* J) \  Y
  6. #define GPIO_FullRemap_USART3 ((uint32_t)0x00140030)5 g$ V- G& T, S8 T
复制代码
5 N# }7 s8 _- y' ~
从上面可以看出,USART1 只有一种重映射,而对于 USART3,存在部分重映射和完全重映射。所谓部分重映射就是部分管脚和默认的是一样的,而部分管脚是重新映射到其他管脚。而完全重映射就是所有管脚都重新映射到其他管脚。看看手册中的 USART3 重映射表:
3 F, T8 l+ k9 }4 g& S8 @! {- }* j. U5 n& a& C0 |) B( C
4 B5 O$ r# A, H+ i
20201204173139398.png ; W; n: I& m$ L, P# I7 K

9 s  J) g+ M' `: W0 a
! x% h  Z* ^- B0 f+ T) ]. ]
部分重映射就是 PB10,PB11,PB12 重映射到 PC10,PC11,PC12 上。而 PB13 和 PB14 和没有重映射情况是一样的,都是 USART3_CTS 和 USART3_RTS 对应管脚。完全重映射就是将这两个脚重新映射到 PD11 和 PD12 上去。我们要使用 USART3 的部分重映射,我们调用函数方法为:
4 u$ [9 n0 y0 l* d$ f# S3 t5 H
  1. GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);6 O# {! [8 o/ Y* L
复制代码

* v& T5 C1 \  U0 k/ }# J! {————————————————
, L9 {! t( d% Q5 o1 g版权声明:FHNCSDN
1 O  u: n3 p1 l6 f/ T2 I9 w3 }如有侵权请联系删除, F. c) `+ R2 v+ }' {6 r" I
/ Z1 p6 m  R5 X7 C) B7 T: J) F
# q* F: Q) q' ?' s* M* F
收藏 评论0 发布时间:2023-5-15 19:07

举报

0个回答

所属标签

相似分享

官网相关资源

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