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

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

[复制链接]
攻城狮Melo 发布时间:2023-5-15 19:07
端口复用功能: z9 b" `% q3 G% S+ K& D9 y
        STM32 有很多的内置外设(比如:串口、ADC、DAC等是独立的模块和内核连接在一起),这些外设的外部引脚都是与 GPIO 复用的。也就是说,一个 GPIO如果可以复用为内置外设的功能引脚,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。4 i& }. ]( i$ C1 t# k9 s
        大家都知道,MCU 都有串口,STM32 有好几个串口。比如说 STM32F103ZET6 有 5 个串口,我们可以查手册知道,串口 1 的引脚对应的 IO 为 PA9,PA10.PA9,PA10 默认功能是 GPIO,所以当PA9,PA10 引脚作为串口 1 的 TX,RX 引脚使用的时候,那就是端口复用。查看芯片资料可知道那些口是复用端口。
% o+ [# m! @; i- X3 g' _: W/ d$ H* T: U0 O4 a6 `6 J6 M
1 G/ q5 H! a4 |5 v  U
复用端口初始化有几个步骤:$ m, o' h& P1 x
7 e! M$ A) a0 W& {0 N' m$ i

# v# w/ J; W9 |' o& P9 {% lGPIO 端口时钟使能。要使用到端口复用,当然要使能端口的时钟了。
1 G& `. b! J, ^! I; _
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    5 a1 l- S* x+ n# @
复制代码
0 H8 t* b) v' w' k
复用的外设时钟使能。比如你要将端口 PA9,PA10 复用为串口,所以要使能串口时钟。
- i- L+ D! D) n  Z3 A7 ]
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);. |6 |' ~, l, I$ W; ]
复制代码

" y  @. M1 r+ e* ~9 l+ e/ Y端口模式配置。 在 IO 复用为内置外设功能引脚的时候,必须设置 GPIO 端口的模式,至于 在复用功能下 GPIO 的模式是怎么对应的,这个可以查看手册《STM32 中文参考手册 V10》 P110 的表格“8.1.11 外设的 GPIO 配置”。这里我们拿 Usart1 举例:0 Q2 Z- `3 t- \# \% [; [
7 k( C0 e1 X$ b7 n1 u& O8 c

8 u: p& d4 f7 b& s' b 20201204162037509.png ( {4 w0 v  S$ N8 W" X4 j

1 Y3 I! b- z6 B5 i" E" t2 m6 b

6 q7 s0 D) Z- U* @" U. U从表格中可以看出,我们要配置全双工的串口 1,那么 TX 管脚需要配置为推挽复用输出,RX 管脚配置为浮空输入或者带上拉输入。
; }9 A( F1 O0 R; R& f" u- Z8 a# I- u4 L4 K/ [
/ Y) w; j9 @5 p: G
代码如下:
) K6 ]2 N1 [! h& u3 ~% A! [
  1. //USART1_TX PA.9 复用推挽输出- J' `# {' b3 r5 {9 N: g6 T4 z
  2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    - V' A& g6 b' L& p2 S5 ~
  3. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;$ P4 e2 O2 h1 N/ n4 q* u9 r4 F' L
  4. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    ( P0 N7 o0 E  P1 _
  5. GPIO_Init(GPIOA, &GPIO_InitStructure);4 d5 ^# N; F. f% b0 t2 o3 \2 a/ p
  6. //USART1_RX PA.10 浮空输入' P" A4 D. r$ a' S% i) J8 A
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    ; Z5 U' B" {  L, s+ X1 d/ k
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    6 N) J$ ~) a6 ]' x$ `7 ]1 u4 m
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);5 t0 o- T& [8 @# {/ e- u+ @
复制代码
/ I# i. R) `7 ?1 c
我们在使用复用功能的是时候,最少要使能 2 个时钟:
$ W) V! R: H9 n& B7 R8 B, M, AGPIO 时钟使能
  O, }$ U- O- {) {复用的外设时钟使能同时要初始化 GPIO 以及复用外设功能
( w. U  _; @9 f; h; v; `- ~' B& ]2 y; b
$ }2 B! H* A2 V" y2 \
端口重映射
# Z) y6 Y2 a& A6 `        为了使不同器件封装的外设 IO 功能数量达到最优,可以把一些复用功能重新映射到其他一些引脚上。STM32 中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 STM32 中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。. E1 z! W1 d+ s+ q
        简单的讲就是把管脚的外设功能映射到另一个管脚,但不是可以随便映射的,具体对应关系《STM32 中文参考手册 V10》的 P116 页“8.3 复用功能和调试配置”有讲解。这里我们同样拿串口 1 为例来讲解。7 P7 c  |, ?( d9 l
3 j0 w/ `  x% c) }7 a/ F# U

8 |) j; M4 r, \1 P- g, @/ R 20201204163136329.png
( r  K" D- g) E) k+ L. H+ j  R( f: d$ @" x9 o
) e' E# V* P7 l' u: J8 j* w5 N
        上图是截取的中文参考手册中的重映射表,从表中可以看出,默认情况下,串口 1 复用的时候的引脚位 PA9,PA10,同时我们可以将 TX 和 RX 重新映射到管脚 PB6 和 PB7 上面去。
8 E, H2 V! m7 q3 s- s! _        所以重映射我们同样要使能复用功能的时候讲解的 2 个时钟外,还要使能 AFIO 功能时钟,然后要调用重映射函数。详细步骤为:5 M! ~% }, D$ T: o9 g( P; H

1 b4 A0 c( p% n7 T# n  r
8 G' W0 r2 o+ x2 Z2 t: t  [
使能 GPIOB 时钟:
2 k+ F6 L, Z" D- `8 P
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);# ?" f8 x( |- ^
复制代码

4 L# t: U$ a# J1 @: Y  T使能串口 1 时钟:3 D& h2 x8 D3 W4 I5 Q
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    8 @% M7 P! V' X; f- [2 z3 x  J7 T
复制代码

& G5 i+ ^# h, H8 b2 ?9 n. s9 D使能 AFIO 时钟:2 h  }$ t0 \' ]1 _$ L7 J. g
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);6 ^2 a7 h5 ^' K# F
复制代码

- M) u+ ~0 `. }7 r) oPS: 在对寄存器AFIO_MARR,AFIO_EXTICRX和AFIO_EVCP进行读写操作前,应首先打开AFIO时钟。
. [& Q- d9 F- n; ?+ p( E7 U- m: y2 _1、 AFIO_MARR:配置复用功能映射3 p6 K* K* K' K+ u) o- R
2、 AFIO_EXTICRX:配置外部中断线映射5 f9 t3 Y3 L1 p2 }3 E3 U% L
3、 AFIO_EVCP:配置EVENTOUT事件输出$ j: f+ K7 N2 \: l7 U  z6 I
( I/ k; S8 l9 U8 S

; o9 D* \, I8 a. Q5 @1 j开启重映射:
' Z+ j% i6 ?2 y8 W7 E# G
  1. GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
    / |9 O+ h1 f: S: l* J4 n$ x
复制代码
: |) z3 [8 ^5 P. h1 C3 c5 d5 n
这样就将串口的 TX 和 RX 重映射到管脚 PB6 和 PB7 上面了。至于有哪些功能可以重映射,大家除了查看中文参考手册之外,还可以从 GPIO_PinRemapConfig 函数入手查看第一个入口参数的取值范围可以得知。在stm32f10x_gpio.h 文件中定义了取值范围为下面宏定义的标识符,这里我们贴一小部分:# E8 `0 R4 I9 w5 R5 D
  1. #define GPIO_Remap_SPI1 ((uint32_t)0x00000001)
    * H' [$ B) \6 z, d! W$ Y
  2. #define GPIO_Remap_I2C1 ((uint32_t)0x00000002) ) u1 _$ V+ W& c* W* u
  3. #define GPIO_Remap_USART1 ((uint32_t)0x00000004)
    $ W+ M1 G7 \2 L
  4. #define GPIO_Remap_USART2 ((uint32_t)0x00000008)
    & ~5 C7 Y$ o9 m& z
  5. #define GPIO_PartialRemap_USART3 ((uint32_t)0x00140010)
    - V# C3 Q; l$ t3 n/ ]7 J
  6. #define GPIO_FullRemap_USART3 ((uint32_t)0x00140030)
    ) a0 ?+ \( G0 I, r8 b
复制代码
# t, c1 F1 E9 I" O  |5 s& ]
从上面可以看出,USART1 只有一种重映射,而对于 USART3,存在部分重映射和完全重映射。所谓部分重映射就是部分管脚和默认的是一样的,而部分管脚是重新映射到其他管脚。而完全重映射就是所有管脚都重新映射到其他管脚。看看手册中的 USART3 重映射表:0 @4 N% u% p- h% U% O; v$ D
; B9 v* ?+ E; p0 N

' V4 p  K: J' b: f) t2 W- L 20201204173139398.png
9 v8 E6 W; `3 S, X1 a+ s  D# ]' V0 j* h

* H3 w" Q6 Y5 u& H, z( o部分重映射就是 PB10,PB11,PB12 重映射到 PC10,PC11,PC12 上。而 PB13 和 PB14 和没有重映射情况是一样的,都是 USART3_CTS 和 USART3_RTS 对应管脚。完全重映射就是将这两个脚重新映射到 PD11 和 PD12 上去。我们要使用 USART3 的部分重映射,我们调用函数方法为:
. x" u6 P' ^. N% x
  1. GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);. L! H+ t9 X% L! Q5 y
复制代码

( ?2 X' s& ]7 Y————————————————
# S5 @- j$ z- [1 y* ]版权声明:FHNCSDN' ]6 Z7 D0 d& ]0 }
如有侵权请联系删除
0 L, j) d2 z9 Z# U% |5 l* t/ B6 _+ [2 n! Q. N2 k  p
0 Z1 s7 g) D2 S+ N& G
收藏 评论0 发布时间:2023-5-15 19:07

举报

0个回答

所属标签

相似技术帖

官网相关资源

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