本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本; 先简单的介绍一下stm32的GPIO; stm32的GPIO有多种模式: 1.输入浮空 2.输入上拉 3.输入下拉 4.模拟输入 5.开漏输出 6.推挽式输出 7.推挽式复用功能 8.开漏复用功能 stm32GPIO模式设置相关寄存器设置的介绍
5 l* ]! ] z* [7 }2 o
4 w6 ~0 V' d: U7 A
# e0 X! ^5 s+ i3 y
" {' L1 a9 }+ y( E8 a, J k
stm32中文参考手册中对GPIO模式设置对应寄存器的详细介绍:8 i) F6 n# h g1 J; e
$ S4 d5 R7 N/ \5 y
7 ^ g" |, b/ L
& I9 Q$ P( A) a7 i5 e) |
% x0 L& f3 L. S' r% y; Q4 f, j v
, q: v. `, G; t$ L* p J3 F下图为开发板LED的接线图;
: N/ ]% D5 ^/ \
, N0 A% D+ T8 y% x, G$ ~( N W9 D3 |! B, L0 r/ W
根据上面的电路图可知,将GPIOB_0,GPIOF_7和GPIOF_8设置为低电平时,LED将被点亮; 程序代码: LED.h 文件 - #ifndef __LED_H
: y/ T w/ E2 }; ? - #define __LED_H" D) `. k9 g0 r/ U) U7 k* j
- ' f' B& d, c, d3 l2 k
- void GPIO_Init(void);" \& m/ k$ H8 {. n
: G7 A1 q$ P$ E5 B! O9 U8 R9 @8 j% @) l
0 |$ k# o/ ~3 g' U- / U+ X2 L; ^3 S$ ^/ t7 `
- 5 b; ? W, I; K# t+ x
- #endif
复制代码 5 Z4 W5 l. l5 j; s. y+ r
stm32.h 文件
8 k+ ~4 [/ B4 j- #ifndef __STM32_H
. W8 k# W# g& P8 S& ` - #define __STM32_H+ N" G6 T+ g4 ~# o5 z
" y8 `+ U4 A) R e" z0 d- //引脚寄存器定义
0 e, D% Z1 S& _3 u7 l/ y
0 r7 ^* s2 B" s" Y" _/ c6 B- //GPIO对应寄存器起始地址
; m" v8 E- Y2 P" X D! B8 A2 w7 Q+ [ l - ]! m( w7 y1 ^. g( |8 ?5 s
- #define GPIOA 0x40010800, Q+ F$ q" @! x
- #define GPIOB 0x40010C00( k* W# t5 B% }+ ]' y( |
- #define GPIOC 0x40011000/ c6 J4 t: I1 c! x. @, N8 d/ `
- #define GPIOD 0x40011400
) I. R5 G, n6 p F3 ^- B - #define GPIOE 0x40011800
/ i: N: K0 P4 T0 e - #define GPIOF 0x40011C00
& r* _0 Z* {3 {" t# h# J - #define GPIOG 0x40012000
E; i9 e; Q( w* {' ~- k5 ?( J - 4 f8 \( E: Y( u z1 _% n3 ]6 z L
- //寄存器偏移地址
8 V3 v9 k5 k1 C/ ^( J
) t* B" K% A& z. o& k- #define GPIOx_CRL 0x00
! n/ [& N3 f" D0 [" R - #define GPIOx_CRH 0x04
! y5 ]3 i1 }/ G% c7 v' m, {! w - #define GPIOx_IDR 0x08
8 t+ S9 y* A" V# V - #define GPIOx_ODR 0x0c
- D! J% D' m# A" w - #define GPIOx_BSRR 0x109 g3 M/ L! T, }# H& H2 ?
- #define GPIOx_BRR 0x14
, L; Q/ U2 C$ ]% d8 s% S2 U# N- S - #define GPIOx_LCKR 0x18
) N' {9 D; z, m0 H. Z
& F, a1 `( c6 d/ [* e' W8 K
( I0 X: |: g1 C) g F
. U: M- M# s; o6 Q- #define GPIOB_CRL *((volatile unsigned int *)(GPIOB + GPIOx_CRL))+ G5 v: m& l# e6 I0 Y
- #define GPIOB_CRH *((volatile unsigned int *)(GPIOB + GPIOx_CRH))
) Q2 g: s* W0 Z) y( I( ~ - #define GPIOB_IDR *((volatile unsigned int *)(GPIOB + GPIOx_IDR))( V* b8 F) a' l- D
- #define GPIOB_ODR *((volatile unsigned int *)(GPIOB + GPIOx_ODR))
1 b) I8 h% Q! F( @ - #define GPIOB_BSRR *((volatile unsigned int *)(GPIOB + GPIOx_BSRR))
9 W. j1 w" Y# d- h) Y7 i - #define GPIOB_BRR *((volatile unsigned int *)(GPIOB + GPIOx_BRR))
4 e. O8 }6 c H9 \1 z - #define GPIOB_LCKR *((volatile unsigned int *)(GPIOB + GPIOx_LCKR))
# B1 r; C. b K, |0 e
, y* h- G E7 S- S
: W8 D1 K( d2 J4 Z' E
8 l- y( e y ~; B( x4 {- #define GPIOF_CRL *((volatile unsigned int *)(GPIOF + GPIOx_CRL))
7 j1 i: |( ]1 s( x - #define GPIOF_CRH *((volatile unsigned int *)(GPIOF + GPIOx_CRH))* d* \2 c, D0 V
- #define GPIOF_IDR *((volatile unsigned int *)(GPIOF + GPIOx_IDR))9 k, j5 U9 R& ]2 T+ f7 `4 n, v0 i. C
- #define GPIOF_ODR *((volatile unsigned int *)(GPIOF + GPIOx_ODR))
o6 t% J, d* S1 U% U - #define GPIOF_BSRR *((volatile unsigned int *)(GPIOF + GPIOx_BSRR))
$ C4 B4 c6 o" L" d8 q; O - #define GPIOF_BRR *((volatile unsigned int *)(GPIOF + GPIOx_BRR))5 l% g, N& S2 A% t% m, f7 x: G/ M: ]% T
- #define GPIOF_LCKR *((volatile unsigned int *)(GPIOF + GPIOx_LCKR))
+ h7 c9 ], h W! j - % q1 X/ k4 \7 t. n
- 4 Q/ |1 ^! ^+ @% u
- #endif
复制代码
4 N8 h8 e/ B" s& w& Y @/ Z' K0 ]LED.c 文件 - #include "LED.h". X" M D- E- l& Q B% e+ B
- #include "stm32.h"
" j* J0 Z" ^% _% [$ @1 g - - u) i0 m" }7 `% `( v w
- void delay(unsigned int x)
/ N: v5 W$ y A - {
; ^8 L/ F9 C; z) Z$ v6 W/ P - volatile int i, j;
, k( Y3 x7 ?* E- A K1 ^' F - for(i = 0; i < x; i++)
5 M Y& J7 v3 N" L3 l7 [4 f - {
: S, o$ v9 E( S9 ] - for(j = 0; j < 1000; j++);
6 t& J& b4 A# Q& }& |) Y - }+ `, [8 K- b8 l8 s5 s: q6 K
- }5 r/ D- ]9 Y7 |5 V
6 T6 r+ W# p" X% {5 v- void GPIO_Init(void)
# r1 I5 B5 l. A c9 t - {3 p4 O8 v3 F* y
- //使能GPIOB和GPIOF的时钟
' k7 X! ?) r( c+ c1 Y1 H& c - RCC_APB2ENR |= 1 << 3;
0 O% l9 H J& I& v* } - RCC_APB2ENR |= 1 << 7;% i$ b, E7 ~8 U+ K( C
- / ]+ D2 A' {7 Q- |, b7 d& U
- //清除GPIOB和GPIOF的配置寄存器/ O8 b) T8 K- I" d
- GPIOB_CRL &= ~(0xf << 0);
! F z% U$ {* P - GPIOF_CRL &= ~(0xf << 0);3 x( o3 I" w, u" v2 o! ?2 v
- GPIOF_CRH &= ~(0xf << 0);/ Q# n( H ?0 o3 ^* W
- ; J1 z/ L F1 a) @0 q
- //配置GPIOB和GPIOF的端口为通用推挽输出,输出速度为50HZ s% t* b8 k. {& l; g/ v/ b. s
- GPIOB_CRL |= 3 << 0;3 o! |; }8 q# h
- GPIOF_CRL |= 3 << 28;' k: C" d( w9 t
- GPIOF_CRH |= 3 << 0;
( J* h+ N6 K) x0 F - B1 |2 Z$ g9 |. \' Z+ Q
- //设置GPIOB_0和GPIOF_7和GPIOF_8输出为高电平
* C, _( c/ y% U4 H0 Q. O1 B - GPIOB_ODR |= 1 << 0;
: T+ G0 [9 N D4 _/ J7 B5 @- [' z - GPIOF_ODR |= 3 << 7;
, [* P# U: x6 |2 t - }
1 o: j8 n3 R# C1 O0 k( ^: P; ]! A
, g9 Q8 ?1 x' {7 i2 D, I! H5 ]$ Z9 _- int main(void)5 P5 v2 }( J% W& H
- {% U, v+ k8 g, y7 Z6 v" K" L0 i
- GPIO_Init();5 e2 h4 Y# L% h& T0 W
- 5 ?/ z" Z" l- W2 [4 ^
- GPIOB_ODR &= ~(1 << 0); //设置GPIOB_0端口输出为低电平+ t( R* T2 m8 |5 [7 n
- GPIOF_ODR &= ~(3 << 7); //设置GPIOF_7和GPIOF_8输出为低电平
6 W8 m% c* ~5 {# p; V( b - while(1): b7 \$ i1 P- Y# ]: t. F' u5 F
- {
4 N) P1 W! r8 \ - GPIOB_ODR &= ~(1 << 0); //设置GPIOB_0端口输出为低电平3 b( Y$ V9 W: R0 C8 f
- GPIOF_ODR |= 3 << 7; //设置GPIOF_7和GPIOF_8输出为高电平
; {( e+ a3 e3 ]& L* g - delay(100);9 ?& f3 e5 F1 K6 a+ T
- 0 g% C' h7 b4 K* f6 o- E5 ^
- GPIOB_ODR |= 1 << 0; //设置GPIOB_0端口输出为高电平
% V- z# J+ z. t2 g - GPIOF_ODR &= ~(1 << 7); //设置GPIOF_7输出为低电平- D, j; y2 z1 U# B8 J
- delay(100);
. }. k3 i8 O4 i
: K; Y! X/ ^* d0 |- w- GPIOF_ODR &= ~(1 << 8); //设置GPIOF_7输出为高电平/ u& X4 n- Z/ M" D, b
- GPIOF_ODR |= 1 << 7; //设置GPIOF_8输出为低电平# Y/ a6 _- d* w$ H9 A% J! b. H
- delay(100);
# L# x3 L. o" _+ r# x$ N - }
# T( T' P/ X& i' e2 \% Z* E
9 `' v3 H. R j, t4 N- }
复制代码
- ~- U8 ^ t! @
o6 ?4 H) o/ X% |1 e. U, R9 D2 O程序将实现流水灯的效果; 在使用GPIO时一定要将相应GPIO的时钟开启;
# Z$ W ~4 D& ]1 S; O: U' ~: m2 g. v) N9 g |