GPIO口
6 ]" p3 S$ @0 j
+ s; f4 A' m+ h W% A/ ]5 [! v
# i2 J8 y5 M$ M: ~
" G& ^8 g! {% }1 [+ i% h* l8 v, @) ^: M; u* C* E% L+ g
介绍:
+ B# X* j9 Z! v
" g! I; |# z- ^( S3 _5 ~: ?4 个 32 位 配 置 寄 存 器% e: f) j) {* D i" G2 L7 p( |
5 t* V m2 |' k9 K* g2 a: P
GPIOx_MODER:模式配置寄存器
0 ]" V" ^# N; L3 h) f4 @8 W. G* \
' z8 T. p2 N5 u" [+ s+ Q' GGPIOx_OTYPER:输出模式配置寄存器 n4 [' q& u6 Q: C5 @: F! k2 H
7 K2 q) T7 \$ O" N6 @: |
GPIOx_OSPEEDR:输出速度寄存器5 r1 @" h& |4 U" F; n# G
, _5 a+ u1 y: L' X: z
GPIOx_PUPDR:上拉下拉选择' e4 l! I- A2 Z
5 \3 Y x/ D% o+ }% G& _: k- k( C2 个 32 位数据寄存器
+ A( K4 J o4 C- v) V
0 j- K( g4 L: n! pGPIOx_IDR:输入寄存器
9 L1 O4 w2 ^6 A, y2 [" ?/ M* R0 r; T8 N+ b5 r2 S' k/ a+ n" a
GPIOx_ODR:输出寄存器
# Z; p; O: c( @! p1 {
3 }; \& T- g+ V7 G! m3 f1 个32 位置位 / 复位寄存器
2 [2 d: c2 ]% w9 L1 ?
$ y3 @4 c) V+ ]& EGPIOx_BSRR" [. x/ d7 z0 U3 X6 {5 i
4 b6 ?, d$ D9 l8 m& w+ f% S. w
A和B还含有1个32位锁定寄存器 ?: i+ N. y9 a' l4 v
; c, i8 f7 i8 N$ J* k! n: p, Z% XGPIOx_LCKR
2 }/ E+ R5 X& T4 W# R, `6 i7 R8 }) w) Q ]2 U( t2 j
A和B还含有2个32位替代功能寄存器
' K3 j) m2 Y3 \" V' M6 M4 e% l8 R6 d" E% M
GPIOx_AFRH :复用功能寄存器3 p# l5 w' G; B
: ^/ H, r6 @# L! j% S; f* JGPIOx_AFRL :复用功能寄存器! [& e( L2 L& o0 ~+ Y
7 r; A) G$ J( R; w* g" E" ]GPIO口可以配置成如下模式:
8 V+ }* w; a- I {1 q/ U+ C$ C' Q! J# [
● 浮空输入9 _) e0 i- c5 k5 ~+ J5 [) z9 E- ~
- U2 B9 X& }+ x/ B8 c: {. f
● 上拉输入
: p# i/ r; m+ F# ]/ |0 Z
5 J3 v* T4 p2 K7 V$ z# s& R% X● 下拉输入7 M8 C8 Y, ? t6 g( M
. B6 k5 c* V8 i0 e7 E
● 模拟输入
6 V; K# U# a; t! ]/ _: t& }) p. Y
2 a6 b) P* z9 l. }0 Z) O" J( ^, \( L● 具有上拉或下拉能力的开漏输出- L3 n# G" B* X, o5 Q1 p3 B
2 w0 d* K4 b6 t2 i2 Z
● 具有上拉或下拉能力的推挽输出1 F4 E6 w' t( @. M3 w
. l( h- t9 Z! R1 y
● 复用功能且具有上拉或下拉能力的推挽输出/ H$ e" S! B( F. A7 M
* y M2 I1 a8 L7 S& c1 r
● 复用功能且具有上拉或下拉能力的开漏输出
( e0 j: i* R5 Y, z2 y( J
M! x8 \% l9 Z注意事项:5 s- A: }5 m, O& L; E+ P$ V
+ D% `% e1 l9 B% u: K1:所有端口都有外部中断能力。 为了用做外部中断口线, 端口线必须配置为输入模式8 i) X$ l5 m9 ^9 g# I( G
3 M' |; k( B8 X4 q9 N8 I, {2:对于 GPIOx_ODR 中的每位, 在GPIOx_BSRR 中有两位与之对应: BS(i) 和 BR(i)。 当对位
Z: r1 z1 M: ^" @4 E X
|& k0 M* {( z. C2 dBS(i) 写1时则设置相应的 ODR(i) 位。 当对 BR(i) 写1时, 则复位相应的 ODR(i) 位。
% X2 d) R0 K0 v; D
& @9 H9 `' S0 b# X3:为了写 GPIOx_LCKR 寄存器, 须发出一个特定的写 / 读序列。 当正确的锁定序列作用于这个" q' a; D' l/ O( h8 l: s
+ U" G' l ], z `1 A4 l1 o( u寄存器的位 16 时, LCKR[15:0] 的值用来锁定 I/O 口的配置
( n9 ? l9 T1 r4 e9 y: H9 _1 y6 N" [4 {" c6 R; a
配置过程:
! b% k a- p3 X. a8 P7 q h. Z! c
" f: U: G2 A, D- k- void GPIOConfigure( void )
2 u" C4 ]0 Y6 x' l& y! X/ r/ _. q
/ L! [1 A" V+ J/ z- S, Z$ G+ @. U- {
, X& O6 S: B- Y8 U. a' j - GPIO_InitTypeDef gpio_init_structure;, p. j: ]/ K4 z' {; X6 V
1 c* q! M" P+ ]) ?1 S8 Q; A9 `" g- gpio_init_structure.GPIO_Mode = GPIO_Mode_OUT; //输出模式
# ?$ R7 y! \& u6 o
% V1 s! F$ z, j+ f) o' ]- gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz; //输出速度
4 U; i+ _0 ?! B9 G' V; X. \2 D1 x) D, k - - f. f' L9 J& J' [2 f
- gpio_init_structure.GPIO_Pin = GPIO_Pin_0; //引脚
4 B. _, D* D9 [! F) ]/ q$ s( p$ T! k - * ]% S9 I' {% O1 h W4 x
- gpio_init_structure.GPIO_PuPd = GPIO_PuPd_UP; //上拉模式输出/ e% W& D. R8 W9 @. w
8 k: o6 W7 o' D* x! t8 H- gpio_init_structure.GPIO_OType = GPIO_OType_PP; //推挽模式输出
, @2 R' @$ y3 D( \3 c$ c J- M$ g
# p4 @' D w. X# f W- , t! T: [' w+ E
( O% ~+ M, T- E- `" | U- GPIO_Init(GPIOA,&gpio_init_structure);
9 p6 B8 C: J( e2 `6 H0 c& Q4 O [
8 j) z- l# C$ W$ W- }
复制代码- #define GPIOA_SET_BIT0 GPIO_SetBits(GPIOA,GPIO_Pin_0)//置位
: V$ M$ T* u$ t$ y9 x; E- T$ W - 5 r/ S2 r( F2 b: |+ N% C9 A# `
- #define GPIOA_RSET_BIT0 GPIO_ResetBits(GPIOA ,GPIO_Pin_0)//复位
7 i, b$ R1 j% ~" t5 n }
4 v2 k% ?6 ^( A3 l; x- #define GPIOA_RDIN_ALL GPIO_ReadInputData(GPIOA)9 i0 E$ k& S( E e- ^& e; Q
- % K) p% M4 ~+ X+ W
- #define GPIOA_RDIN_BIT0 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)2 B; n6 c) T0 R" X
- 5 x' Y* p; o) y/ l% z
- #define GPIOA_RDOUT_ALL GPIO_ReadOutputData(GPIOA)
) Y. X$ X% J: X( m, Z - 5 b* v# V2 C9 T; Y+ Y& m* W9 y
- #define GPIOA_RDOUT_BIT0 GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)
复制代码 ; o4 }4 H8 V$ B
上面是相应的读取和写入函数,看函数名就可以理解此函数的功能0 ~- I4 m/ R. N9 Z; T* Q1 z
8 \1 x. B7 c! k- n6 g- int main(void)
* i+ I: o. g! k - {! J" J+ t, G P" k
- //- N% k$ K6 N# f9 A w
- unsigned long i;
! g' O/ C. z+ f. E - 5 X; C9 {/ j) ~3 ^1 e$ ^
& d8 G! j1 ^6 M! X- //
) L9 M% r, D( o/ _ - RCC->AHBENR |= 1 << 17; // 开启GPIOA外设时钟: o0 F: u/ ^" e5 q0 L" Y
- GPIOA->BSRR = 0xFFFF; // 清除全部端口/ n; x/ K! H4 }/ G ~
- GPIOA->MODER |= 1 << 2; // 配置PA1 通用输出模式
8 x) @; { v# V# V; P - GPIOA->OTYPER &= 0xFFFD; // 配置PA1 推挽输出) S6 v5 j: S, |8 ~3 y# s8 u
- GPIOA->PUPDR &= 0xFFFFFFF3; // 配置PA1 没有上下拉& a2 b; C5 [# [, R2 e) l, j
- GPIOA->OSPEEDR &= 0xFFFFFFFF; // 配置PA1 输出低速模式, t) w4 B- k- z) L! N
2 e+ U, @0 k( T9 o2 \- i = 2000000;
; ]' m3 o# A& |8 E - //5 O z' w& N! U k
- while(1)1 r! d' G' p( W/ o8 J- g
- {( n9 Z9 D0 v2 i+ O
- //2 U, Y# F2 e- ^; j
- if(i > 1000000)9 l7 k7 _, v% d# J: z
- GPIOA->BSRR = 1 << 1;# d) f% v% e' r W/ q0 T' b9 `# g, }3 ?
- else3 T* }1 V$ @( `
- GPIOA->BSRR = 1 << 17;
$ M5 n2 b. u2 I! y) e+ C4 u - if(i == 0)
* J R7 f! a$ Z - i = 2000000;
% ~/ K/ `9 t. Q; Y - else: r/ C$ J1 O1 q2 `
- i--;5 ?* R1 T% }9 F. }2 T$ h6 V
- //
8 G0 O5 s. Q1 Y( U - //
( B, a7 Y4 {5 Y/ o - }
1 B3 u) W" { X. ?( P7 K' ] ]+ G - //) j8 R7 B- S" e* I
- }
复制代码- void I2C_MyInit(void)
' J0 T x/ j9 b2 q1 ^ - {( W& _. M2 }, D* U
- GPIO_InitTypeDef GPIO_InitStructA;2 G4 o5 d& g- V& a- f
- 5 e$ Q( c) E1 U S
-
( `9 z, a% @) G0 ~ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOF,ENABLE); 1 t5 g) d5 x( f3 y0 N4 p# O
+ y4 i9 g( A. p& H- //I2C模拟
; m* h* L& d, c* Z2 X - GPIO_InitStructA.GPIO_Pin =SCL_GPIO|SDA_GPIO;
+ L1 n E# q/ a5 \ - GPIO_InitStructA.GPIO_Mode = GPIO_Mode_OUT; //GPIO_Mode_IN)输入 (GPIO_Mode_OUT) 输出 GPIO_Mode_AF第二功能 (GPIO_Mode_AN)模拟
4 ~( c% I4 ~+ p% N* Q# [3 h5 l0 U0 l4 O - GPIO_InitStructA.GPIO_OType=GPIO_OType_PP; //GPIO_PuPd_NOPULL(不拉),GPIO_PuPd_UP(上拉),GPIO_PuPd_DOWN(下拉)
e$ S5 z; E- Z. U - GPIO_InitStructA.GPIO_Speed= GPIO_Speed_50MHz;
$ G5 m) r: o+ _# h& G: C% J - GPIO_Init(GPIOA, &GPIO_InitStructA);$ r( j# G0 s& O w
- GPIO_SetBits(GPIOA,SCL_GPIO|SDA_GPIO); //PA0,PA2输出高
+ _* c6 P; K: x( F' `; h9 j6 @' Q - }
( r% I* _6 a! d - void SDA_IN(void); o1 Z/ L' n; m! s& Z
- {. @$ c$ k: ]; ]& t' k
- GPIO_InitTypeDef GPIO_InitStructA;
% V7 o7 h. \* G# D
. L+ J) S$ p% K. C-
* E( B$ O" N- [' S. N( E - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOF,ENABLE);
4 K; {1 o; ]* e; {! n9 K: {9 N
0 s8 p( } r- ?. [( h1 ^- //I2C模拟$ I, M' y6 _# O+ }4 T
- GPIO_InitStructA.GPIO_Pin =SDA_GPIO;" ]4 Q. Z2 P% ^$ L. t8 X
- GPIO_InitStructA.GPIO_Mode = GPIO_Mode_IN; //GPIO_Mode_IN)输入 (GPIO_Mode_OUT) 输出 GPIO_Mode_AF第二功能 (GPIO_Mode_AN)模拟
# g$ T. U6 L) t! _# f. H - GPIO_InitStructA.GPIO_PuPd=GPIO_PuPd_NOPULL; //GPIO_PuPd_NOPULL(不拉),GPIO_PuPd_UP(上拉),GPIO_PuPd_DOWN(下拉)0 w6 O/ O" x% ~8 w2 E* {4 Y
- GPIO_Init(GPIOA, &GPIO_InitStructA);
S3 N# j, V2 F! o! z - }: L3 I4 i0 P1 b! @" h
- % |5 m* o+ ]8 E, Q8 T3 C2 Y% p
- void SDA_OUT(void)
8 e& z6 }* v4 I& _ - {3 m$ {. F+ f( r6 T# i9 @- r- q) N) l
- GPIO_InitTypeDef GPIO_InitStructA;
8 I. c4 }$ U, R - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOF,ENABLE); 3 e! B1 p. m, X$ W% s, d
- 2 |4 m( i7 [7 M: {# T
- //I2C模拟: h9 D: d( r5 @3 E- w. w
- GPIO_InitStructA.GPIO_Pin =SDA_GPIO;
7 G2 d3 K1 M8 r/ A1 S1 T5 ^ - GPIO_InitStructA.GPIO_Mode = GPIO_Mode_OUT; //GPIO_Mode_IN)输入 (GPIO_Mode_OUT) 输出 GPIO_Mode_AF第二功能 (GPIO_Mode_AN)模拟( h" f8 }. h- E" H9 q" f
- GPIO_InitStructA.GPIO_OType=GPIO_OType_PP; //GPIO_PuPd_NOPULL(不拉),GPIO_PuPd_UP(上拉),GPIO_PuPd_DOWN(下拉)
7 q9 _: J" u7 ]% P! @- f. E - GPIO_InitStructA.GPIO_Speed= GPIO_Speed_50MHz;
2 s, W+ ]6 ?" g0 B$ h; K1 z - GPIO_Init(GPIOA, &GPIO_InitStructA); N9 Y+ T% y0 ?
! C1 Y6 y% S$ g/ }& n: X- }
复制代码 5 z6 Y; B! a, d g7 G! F( f
( g! {- T* x" S- g& }
7 [+ S* W; T# [2 t& o4 m- I/ v |