端口复用的定义 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)
# X7 T/ @" t* q( _( ] - #define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002)- C4 m+ V- _; T& D, r
- #define RCC_AHB1Periph_GPIOC ((uint32_t)0x00000004)
& h! X; l7 T2 i7 Q- y- r( | - #define RCC_AHB1Periph_GPIOD ((uint32_t)0x00000008)
9 ]# p# q) n. P - #define RCC_AHB1Periph_GPIOE ((uint32_t)0x00000010)' D6 j! i. D' g5 g) ~: {
- #define RCC_AHB1Periph_GPIOF ((uint32_t)0x00000020)
( ~; H$ z7 S9 k7 N7 H5 J - #define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040)+ g: r" T+ h! j) y( J6 |) B
- #define RCC_AHB1Periph_GPIOH ((uint32_t)0x00000080)% | S7 [. W2 v' t
- #define RCC_AHB1Periph_GPIOI ((uint32_t)0x00000100)3 O8 `8 b7 d p: W8 p* B
- #define RCC_AHB1Periph_GPIOJ ((uint32_t)0x00000200)
8 l( D ]: {, U$ Y n* C) d - #define RCC_AHB1Periph_GPIOK ((uint32_t)0x00000400)
a2 z! O5 h, C - #define RCC_AHB1Periph_CRC ((uint32_t)0x00001000)
6 `% l0 n# s3 P, ~5 P' g2 | - #define RCC_AHB1Periph_FLITF ((uint32_t)0x00008000)' s ~2 ?; J( A5 R( s) a: q, c
- #define RCC_AHB1Periph_SRAM1 ((uint32_t)0x00010000)
# R* A) e0 W. t% g+ f8 `, b - #define RCC_AHB1Periph_SRAM2 ((uint32_t)0x00020000) l ?3 i a+ i) ]: ?
- #define RCC_AHB1Periph_BKPSRAM ((uint32_t)0x00040000)3 V: F' V7 L3 m) B; C2 f& t2 L
- #define RCC_AHB1Periph_SRAM3 ((uint32_t)0x00080000)5 _% U& [ n1 S6 ^: M# B) p
- #define RCC_AHB1Periph_CCMDATARAMEN ((uint32_t)0x00100000)
3 T. L% H @2 l) [ N6 Z - #define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000)
E5 g" E% d2 t% L" m' n7 i - #define RCC_AHB1Periph_DMA2 ((uint32_t)0x00400000)! R! e( I e$ g0 ?0 M3 r
- #define RCC_AHB1Periph_DMA2D ((uint32_t)0x00800000)
) m! ~ ^( t, y3 U$ a; A - #define RCC_AHB1Periph_ETH_MAC ((uint32_t)0x02000000)2 B% K G$ y4 a7 o
- #define RCC_AHB1Periph_ETH_MAC_Tx ((uint32_t)0x04000000)
; N$ R2 T* I, D/ c - #define RCC_AHB1Periph_ETH_MAC_Rx ((uint32_t)0x08000000)$ |3 R: V5 {* Y% s7 E& N4 o4 a, d
- #define RCC_AHB1Periph_ETH_MAC_PTP ((uint32_t)0x10000000)! Q% X9 k+ M) i6 y+ G7 a) m W
- #define RCC_AHB1Periph_OTG_HS ((uint32_t)0x20000000)
) f- {# k, Z' P$ L* w1 j* q7 s i - #define RCC_AHB1Periph_OTG_HS_ULPI ((uint32_t)0x40000000)
复制代码 % w" ]; x8 y/ `, f- a/ L3 t
端口复用初始化过程接下来看一下端口复用初始化过程的步骤,拿串口1为例: 1、GPIO端口时钟使能。要使用到端口复用,首先是要使能端口的时钟了; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 2、复用的外设时钟使能。比如要将PA9、PA10引脚复用成串口,必须也要使能串口时钟;
5 g5 w' G+ C; ?0 V2 @: _' F" v$ PRCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 3、端口模式配置。在I/O复用位内置外设功能引脚的时候,必须设置GPIO端口的模式。至于在复用功能下,GPIO的模式怎么设置,可以查看手册《STM32中文参考手册》p110的内容。这里拿USART1为例,进行配置,要配置全双工的串口1,TX引脚需要推挽复用输出,RX引脚需要浮空输入或者上拉输入; , ^7 R# O/ x4 T, j
- <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>+ ?1 C! E. m7 G6 M/ M8 r8 g
- <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>
复制代码 4 w5 D& m. z* d4 K( v, f
总而言之,使用复用功能的时候至少要使能2时钟:GPIO时钟使能、复用的外设时钟使能。同时还要初始化GPIO以及复用外设功能(端口模式配置)。 . }- M, a1 b) S. }* \3 q7 [, C
|