本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本; 先简单的介绍一下stm32的GPIO; stm32的GPIO有多种模式: 1.输入浮空 2.输入上拉 3.输入下拉 4.模拟输入 5.开漏输出 6.推挽式输出 7.推挽式复用功能 8.开漏复用功能 stm32GPIO模式设置相关寄存器设置的介绍 - ?; z1 Z2 D- Z# E6 P
8 [6 g5 b! ~# V+ F+ w: ^5 u( Q i
4 T) w4 z# P8 u! _* G8 r+ {) l& E( t
stm32中文参考手册中对GPIO模式设置对应寄存器的详细介绍:4 e/ G& E. H: K1 q! _, {1 s
% d7 h3 s9 q$ I" j& @, G
5 G* z7 h8 n8 z& }6 _! F0 U" P% L
\: ^' t$ K' a5 T* Q O0 q
3 y: F1 Z* U( @0 ]9 e7 o j, N. F( P
5 U' }0 k @# q1 N7 R( f# ?
下图为开发板LED的接线图;
1 i5 Z2 S) H |0 v, N5 ~$ E3 S! p2 @, R
2 J0 T4 k' b; F# q
根据上面的电路图可知,将GPIOB_0,GPIOF_7和GPIOF_8设置为低电平时,LED将被点亮; 程序代码: LED.h 文件 - #ifndef __LED_H/ B a+ B1 i m
- #define __LED_H R6 q3 `; c) e2 g6 T n0 M$ l
5 C8 ]. [% c; }- void GPIO_Init(void);
- ^3 P% L0 Y' k% _- g: x - ' T4 o, N% D2 L# b) r' [9 S1 w
- 0 W1 g; B! G% V# l; n3 ^
. ~+ ]( n$ H% t2 s6 d% \9 H4 i! e
3 v, N) Z& v# C: e+ x8 `' ]- #endif
复制代码 0 _# y' W8 g% W. G7 @: P
stm32.h 文件
0 K0 D$ R4 J2 R! E/ }3 ^4 S/ r/ Q I1 [- #ifndef __STM32_H3 ~( W% K; {0 ]: A7 O
- #define __STM32_H
5 s+ Q# ` {! V! N9 w
n# v v3 i& u( J2 _/ O- //引脚寄存器定义
2 U4 I' z6 U% ~2 a/ }4 z* m3 [ - ( x% @. ^( T: C2 q- |$ `
- //GPIO对应寄存器起始地址
! ]9 [" o: q' }8 d( s
$ }) {: r1 R# S" U- #define GPIOA 0x40010800
+ N- L4 i$ Z# Z5 U0 t( F4 D - #define GPIOB 0x40010C00
: F D' h( ~) ]0 N9 Y0 k* S - #define GPIOC 0x40011000
, C8 K; c% l1 a6 _' |! B0 ` - #define GPIOD 0x40011400
) w( D* w& o, G* V: s( W6 j - #define GPIOE 0x400118003 \, q! g9 c0 J2 q0 V
- #define GPIOF 0x40011C00
* M$ q( ]: m0 ?: O# U' _5 \* J - #define GPIOG 0x40012000& K; G7 [: S1 j
- 6 f8 v1 s; L5 g! Q9 j
- //寄存器偏移地址8 B& Y( \2 ]) ~4 ^+ H
- ' J* v+ p, u9 m( X# p
- #define GPIOx_CRL 0x00
1 o R9 S( ?; o9 c: V# y# F" \, F' T6 L - #define GPIOx_CRH 0x04$ T% O7 V5 m) W0 c2 f# G7 y& |
- #define GPIOx_IDR 0x08- S7 m. X4 N0 ?6 G/ U5 |0 S* O& y" @
- #define GPIOx_ODR 0x0c
5 V x' R3 Q0 M2 _& n* _) u% O% d1 P# p - #define GPIOx_BSRR 0x10, j. k& _+ ]. N
- #define GPIOx_BRR 0x14
' F0 ]/ g$ _( t! k" k - #define GPIOx_LCKR 0x18
: ? X! {+ g3 i' _( @3 T+ J - 1 O: ]) v L9 J% B
- / I i7 E* |& w, ]/ ?
" ~- G0 ?8 g; @. E8 z0 [- #define GPIOB_CRL *((volatile unsigned int *)(GPIOB + GPIOx_CRL))- l8 n) ?# |1 \# i* p5 s
- #define GPIOB_CRH *((volatile unsigned int *)(GPIOB + GPIOx_CRH)): K# s: G9 _. C! X/ | r1 ^6 }% F& Y
- #define GPIOB_IDR *((volatile unsigned int *)(GPIOB + GPIOx_IDR))8 B6 P O) Y* |3 ]9 _' P2 E1 F7 ?
- #define GPIOB_ODR *((volatile unsigned int *)(GPIOB + GPIOx_ODR))
) }" d7 d x9 d" _4 E5 u$ K6 y - #define GPIOB_BSRR *((volatile unsigned int *)(GPIOB + GPIOx_BSRR))
- {( X# u) r- M" I: l7 N, E - #define GPIOB_BRR *((volatile unsigned int *)(GPIOB + GPIOx_BRR))
- ] X+ O5 P6 |7 e+ } - #define GPIOB_LCKR *((volatile unsigned int *)(GPIOB + GPIOx_LCKR))
3 L2 K+ u8 P* r2 a - ! t& ]: H! u8 A# M) b
- 0 G) ~& J8 D: I' N4 _! u( i
- 4 _3 U$ C$ X# N: ]
- #define GPIOF_CRL *((volatile unsigned int *)(GPIOF + GPIOx_CRL))
! Y- G Z* \; L1 K( z - #define GPIOF_CRH *((volatile unsigned int *)(GPIOF + GPIOx_CRH))
& o. i3 r% l$ E) k% ~* J# }1 l$ _ - #define GPIOF_IDR *((volatile unsigned int *)(GPIOF + GPIOx_IDR))' E7 l" A. Z3 N; ]9 m; O
- #define GPIOF_ODR *((volatile unsigned int *)(GPIOF + GPIOx_ODR))
% o) S. z: X- A - #define GPIOF_BSRR *((volatile unsigned int *)(GPIOF + GPIOx_BSRR))
8 A! [' |$ L. H8 P3 J - #define GPIOF_BRR *((volatile unsigned int *)(GPIOF + GPIOx_BRR))
! l9 }( m! o4 ]6 a/ s - #define GPIOF_LCKR *((volatile unsigned int *)(GPIOF + GPIOx_LCKR))
6 Q7 u5 U5 ]4 f: Z% ~7 k - 3 [( c$ q! }# b1 U) `
- & m2 g. P% n p( |, z. ^' w
- #endif
复制代码 0 e( D3 \3 [' ]+ [% T4 [9 _$ A8 i9 h
LED.c 文件 - #include "LED.h"' f( m% D5 }' x, G1 t; L* A" V" D
- #include "stm32.h"
; k7 H7 K" u9 a- n% l$ J - 2 k- ^ V5 c6 w* X4 Z3 d8 Y
- void delay(unsigned int x)
1 a9 M, z$ [6 z/ C- Z j L' i1 M - {6 w. b+ P0 ~! q7 K( Z1 ^
- volatile int i, j;
. T- M0 k4 N8 b6 [0 `7 J+ y - for(i = 0; i < x; i++)
( F0 O2 c8 l! \; U7 z& n - {7 H9 C+ V0 s+ n& Z
- for(j = 0; j < 1000; j++);2 q( a1 R$ {2 C" a' Z, s# V6 l+ [
- }1 m4 ?: N4 u$ q
- }2 W/ F2 r1 p- \/ y# p3 y5 u
. f. @3 R- K# y3 N. ]- void GPIO_Init(void)1 y6 {( k3 J5 y6 n5 y" [$ g
- {4 W/ A. g- ]; i! h/ a
- //使能GPIOB和GPIOF的时钟4 [, D( ?0 c& R+ q& V
- RCC_APB2ENR |= 1 << 3;9 I s. e: ~; @( `" j+ X4 k z
- RCC_APB2ENR |= 1 << 7;# C( l( H: a. V3 U* O0 R
$ f, V8 P4 m1 m5 ~- //清除GPIOB和GPIOF的配置寄存器
* w1 p" ~- b! H - GPIOB_CRL &= ~(0xf << 0);
8 f& j. c8 j8 V+ h; T& O% h - GPIOF_CRL &= ~(0xf << 0);
; z+ E3 F; o$ i2 j - GPIOF_CRH &= ~(0xf << 0);
+ s k) P5 L W3 n2 W3 f# ^! g
- s+ [/ G; { \' o* z- //配置GPIOB和GPIOF的端口为通用推挽输出,输出速度为50HZ
2 f2 ~5 ~8 }* a6 N$ ^ - GPIOB_CRL |= 3 << 0;- ]. t9 T. k c& k
- GPIOF_CRL |= 3 << 28;8 C' l k7 I' X; i. Y1 K( X- p
- GPIOF_CRH |= 3 << 0;
" t8 d! w- n: X8 ~: `* _% A
- J& q5 v! T* l6 S- //设置GPIOB_0和GPIOF_7和GPIOF_8输出为高电平0 B! r/ f( ^9 L7 [$ H
- GPIOB_ODR |= 1 << 0;% q2 J$ i8 P5 o- X+ s6 F
- GPIOF_ODR |= 3 << 7;/ z9 |3 R; S9 |# _
- }6 e6 y& P* S9 ?( N
- % @7 q* _4 h/ o" }6 d X
- int main(void)( u4 H1 n; d9 i4 w S
- {3 H' o, E1 w+ A+ A \, y% S# h
- GPIO_Init();
( w/ I* R* @' Q' `% |
! \" m/ \6 ~ I6 h- GPIOB_ODR &= ~(1 << 0); //设置GPIOB_0端口输出为低电平
9 H% u) G2 r" i/ M( z% v - GPIOF_ODR &= ~(3 << 7); //设置GPIOF_7和GPIOF_8输出为低电平
: d5 h. `5 k0 z, } - while(1)' T: m/ |; b9 Y
- {
# v6 ~5 I8 C: {" i; `3 T" { - GPIOB_ODR &= ~(1 << 0); //设置GPIOB_0端口输出为低电平
K- |, H' F( z& ] - GPIOF_ODR |= 3 << 7; //设置GPIOF_7和GPIOF_8输出为高电平
0 C3 P# z, V; |4 t9 j, | - delay(100);- w3 ~6 z1 ]2 e6 f& A8 u
8 ?3 B3 `: W! h; C8 C9 @- GPIOB_ODR |= 1 << 0; //设置GPIOB_0端口输出为高电平
& ~5 `, z4 F5 F' V+ P) V - GPIOF_ODR &= ~(1 << 7); //设置GPIOF_7输出为低电平
# T3 L3 C5 [' c1 P8 C3 J - delay(100);
+ |0 W% L7 \& o) `: E# n9 y - 3 Z r3 k! N# Z7 d; Q. K
- GPIOF_ODR &= ~(1 << 8); //设置GPIOF_7输出为高电平6 Q5 a1 z4 B5 `: Y! I
- GPIOF_ODR |= 1 << 7; //设置GPIOF_8输出为低电平3 w, t9 Q( x& v& U
- delay(100);
B ]+ A( w6 w4 b/ b - }% h& P( Y" W4 e, Z0 e. M
8 ~. M& h; B9 C* M( m# n- }
复制代码 * O1 w- j4 @6 g; L
: T+ x9 X5 ^; B# X
程序将实现流水灯的效果; 在使用GPIO时一定要将相应GPIO的时钟开启;
- G& ~$ _2 G0 Y2 V9 V7 c" R/ v |