端口复用的定义 STM32有许多的内置外设(如串口、ADC、DCA等等),这些外设的外部引脚都是和GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫复用。详细的可以参考《STM32F103ZET6数据手册》p30的内容,表格的倒数第二栏就表示端口复用功能。 比如说,STM32的串口1的引脚对应的I/O位PA9、PA10。而PA9、PA10默认的功能都是GPIO,所以说当PA9、PA10引脚作为串口1使用的时候就是端口复用。 在配置GPIO引脚功能时需要打开对应端口(port)所在的总线时钟,例如: - #define RCC_AHB1Periph_GPIOA ((uint32_t)0x00000001)( e" X: T7 h1 R
- #define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002)
( \3 G) C ^8 a; U. K - #define RCC_AHB1Periph_GPIOC ((uint32_t)0x00000004)
; X4 \& V G% w+ Q" W+ [ - #define RCC_AHB1Periph_GPIOD ((uint32_t)0x00000008)( Z7 G+ I, _+ U& P8 }8 E' O. s
- #define RCC_AHB1Periph_GPIOE ((uint32_t)0x00000010)- M8 S/ \8 F& `' e* Z
- #define RCC_AHB1Periph_GPIOF ((uint32_t)0x00000020)6 M/ p( C0 C9 k
- #define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040)% J4 F' C7 D0 }) b
- #define RCC_AHB1Periph_GPIOH ((uint32_t)0x00000080)6 T: }' @) T& L' Y1 F+ }
- #define RCC_AHB1Periph_GPIOI ((uint32_t)0x00000100)
: u7 m) y6 m" t+ \ u8 U - #define RCC_AHB1Periph_GPIOJ ((uint32_t)0x00000200)
1 a- o' ?( G) Q9 B" w) }, \ - #define RCC_AHB1Periph_GPIOK ((uint32_t)0x00000400)
/ }1 o+ n7 z; \8 L( D - #define RCC_AHB1Periph_CRC ((uint32_t)0x00001000)
: e3 v# V- z# l& b - #define RCC_AHB1Periph_FLITF ((uint32_t)0x00008000)
# A3 d3 h; p" U! v, M4 S) l- ~- A - #define RCC_AHB1Periph_SRAM1 ((uint32_t)0x00010000)
/ K+ h8 O, @* s0 r; m$ ` - #define RCC_AHB1Periph_SRAM2 ((uint32_t)0x00020000). Y4 o. Q" |- A# |, J9 h
- #define RCC_AHB1Periph_BKPSRAM ((uint32_t)0x00040000)
6 _* T8 w9 E% Z0 a# [: ] - #define RCC_AHB1Periph_SRAM3 ((uint32_t)0x00080000)5 y$ N% s6 o0 ]1 ?
- #define RCC_AHB1Periph_CCMDATARAMEN ((uint32_t)0x00100000)( ~0 S" R. I+ A, d2 V
- #define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000)) D+ m! i; |& M e
- #define RCC_AHB1Periph_DMA2 ((uint32_t)0x00400000), X, v* [6 e$ S v% y% ]
- #define RCC_AHB1Periph_DMA2D ((uint32_t)0x00800000)
( C+ @8 R5 d: d* e! _ - #define RCC_AHB1Periph_ETH_MAC ((uint32_t)0x02000000)+ e( C- R; E1 R, b6 u& J. d6 A( |
- #define RCC_AHB1Periph_ETH_MAC_Tx ((uint32_t)0x04000000)% [. ]6 i( L0 C& h) U3 ]) q+ S" `
- #define RCC_AHB1Periph_ETH_MAC_Rx ((uint32_t)0x08000000)0 c6 K% V$ G; n; o! v+ o1 d* @2 z
- #define RCC_AHB1Periph_ETH_MAC_PTP ((uint32_t)0x10000000)
0 G5 E. n8 V9 }* C i6 D - #define RCC_AHB1Periph_OTG_HS ((uint32_t)0x20000000)
6 ~# a. z4 v4 q6 R- v, h; o - #define RCC_AHB1Periph_OTG_HS_ULPI ((uint32_t)0x40000000)
复制代码 + K% G6 Q! z3 b9 G( {7 k0 W0 u
端口复用初始化过程接下来看一下端口复用初始化过程的步骤,拿串口1为例: 1、GPIO端口时钟使能。要使用到端口复用,首先是要使能端口的时钟了; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 2、复用的外设时钟使能。比如要将PA9、PA10引脚复用成串口,必须也要使能串口时钟;
- U6 |2 U5 {! g) ?& ] m$ Q( \" CRCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 3、端口模式配置。在I/O复用位内置外设功能引脚的时候,必须设置GPIO端口的模式。至于在复用功能下,GPIO的模式怎么设置,可以查看手册《STM32中文参考手册》p110的内容。这里拿USART1为例,进行配置,要配置全双工的串口1,TX引脚需要推挽复用输出,RX引脚需要浮空输入或者上拉输入;
( B( ]; J& F. E1 D- <div align="left">GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9//复用推挽输出</div><div align="left">GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;</div><div align="left">GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出</div><div align="left">GPIO_Init(GPIOA, &GPIO_InitStructure);</div>/ d) J" Q! k) b8 U$ s2 c
- <div align="left">GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 PA.10 浮空输入</div><div align="left">GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入</div><div align="left">GPIO_Init(GPIOA, &GPIO_InitStructure);</div>
复制代码 " C3 V7 \/ t& v/ C- Q! ~* [& V
总而言之,使用复用功能的时候至少要使能2时钟:GPIO时钟使能、复用的外设时钟使能。同时还要初始化GPIO以及复用外设功能(端口模式配置)。
& g2 Q3 [/ B: }' l* N! Y. K8 b |