STM32F4(LED) GitHub仓库:http://github.com/XinLiGitHub/STM32F4xx_LED_Example
& Q! p9 o( S) E: x$ |) e0 y2 \: tPS:博文不再更新,后续更新会在GitHub仓库进行。
6 u S2 L& Y8 a% H3 W$ r
* y4 Q o/ j+ p) [+ T0 |) m& H
在实际的项目开发过程中,常常会遇到硬件电路的修改,然后修改的部分就需要修改驱动程序。想这样需求该来该去是程序员们最烦闷的事情(重复劳动痛不欲生啊~)。为了避免或减少重复劳动,就需要在程序的架构上下功夫。接下来以最常见的LED驱动程序为例,进行程序结构设计。; n8 [! X1 T2 t- i7 P. y
. a2 L- w% o2 S6 q( s) U" q1,开发环境: o6 c' J7 R( t! Q. ^. c# D0 o: y
+ v, M/ u" N2 \; B1 U7 V" E0 |
1,固件库:STM32F4xx_DSP_StdPeriph_Lib_V1.8.0
, `. l) }: t/ h' S 2,编译器:ARMCC V5.065 Q" _# B. o- j: {5 @; u
3,IDE:Keil uVision5
0 S9 T3 `+ |! w8 \; Y. H 4,操作系统:Windows 10 专业版/ D5 }# k5 ~; o/ z' x
% I* A' o/ I# s% y
+ w0 j$ k8 K+ s7 }2 G" l* {4 N2,程序源码
4 F# i9 d. {- y7 x h+ a$ ` LED.h文件
( z2 U% R: Z0 |$ h$ N- /**
$ m* _2 b! M- {5 {4 ^3 ~4 K! ? - ******************************************************************************
v0 j3 ]9 l1 R m9 B, L9 r - * @file LED.h
6 J; z0 P8 A) a& y5 Y - * @author XinLi
0 l) s p% k9 H( k3 s - * @version v1.09 W: n e& @ B2 b7 p
- * @date 24-October-2017
" f- Q |. T$ @5 H - * @brief Header file for LED.c module.
- L1 O2 N( P4 P* P - ******************************************************************************
# N$ v4 W$ Y$ ]! }) b& K8 _ - * @attention
2 z9 F; }8 O2 L - *
9 N' a* i2 G/ j3 |+ ? - * <h2><center>Copyright © 2017 XinLi</center></h2>! I y& N8 R: i
- *. {4 t7 ~# Y0 R* E8 N R" [# U
- * This program is free software: you can redistribute it and/or modify
, m/ C) S' }( R4 X5 I6 e8 Q! N, Z - * it under the terms of the GNU General Public License as published by9 E- w" z* b9 Z3 o- w9 Z* o2 G
- * the Free Software Foundation, either version 3 of the License, or& `3 Q. K& e' Y& }7 u
- * (at your option) any later version.
; j5 T& k% Z! L1 P5 A - *
# i! f; e! o7 C2 J$ e8 g8 R - * This program is distributed in the hope that it will be useful,+ h6 S1 t l. P3 E3 N1 e' @; W
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
( C3 S9 w5 h! l: w" H. v `' t - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the3 t; E; [6 p/ `% Q
- * GNU General Public License for more details.) L! l, z4 D7 R
- *
/ r; G8 X4 @2 k, j - * You should have received a copy of the GNU General Public License, A' g$ j% X: s5 ^
- * along with this program. If not, see <http://www.gnu.org/licenses/>.3 C- n, _& K2 t1 U2 O
- *1 b# W2 ~ Z; n
- ******************************************************************************* ]# w. F' N" Y) J, o+ ]* H) v6 \
- */* M; ` g+ |& u/ U
|8 L, T2 ~0 y- #ifndef __LED_H
( X) E! J0 }2 j0 { T- t - #define __LED_H0 H7 \( V, Z/ M9 [( ` B0 I4 Z
- * [# S8 F/ o9 u' _: B3 ~/ b
- #ifdef __cplusplus
& u; u* W; m2 b ]* M. H+ p$ D8 H& R - extern "C" {, }, F+ L1 z( F- l6 b- x5 K
- #endif, o9 s+ _7 Q4 ~/ M0 n' M. }
- 1 ?! F) B& J) W- b. ^* x5 `
- /* Header includes -----------------------------------------------------------*/0 m( H# g2 N7 x. u# b( \+ t
- #include "stm32f4xx.h"! ]3 C2 G8 Z- q* y; ^
3 S% s5 _# [( U" V- /* Macro definitions ---------------------------------------------------------*/: E+ i0 P* B5 B0 n6 c4 K
- #define LEDn (4)
/ M8 C. ~6 {5 w$ a7 y' L$ c8 r2 n
; n0 m1 B! q# Q. n3 ?3 E- #define LED1_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOC ^' p; M* @: P% ^* [
- #define LED1_GPIO GPIOC
; D+ I, O! P/ `; ` - #define LED1_GPIO_Pin GPIO_Pin_09 V& D, `3 x/ Y9 `. S
2 A% z0 D# z5 G" R: K2 Y* [2 O- #define LED2_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOC% O% F7 l& [6 I
- #define LED2_GPIO GPIOC
6 A/ `9 a2 R- L$ f; _4 h3 F, Z$ m2 q3 d - #define LED2_GPIO_Pin GPIO_Pin_1
& R# K8 S- X, P4 B( ?5 J - 8 G, A4 D; f$ b/ I) R
- #define LED3_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB
" n; Z- e5 l8 p* m2 M P% e - #define LED3_GPIO GPIOB! Y2 |& d$ G a
- #define LED3_GPIO_Pin GPIO_Pin_3: s3 p: l: D- t; {( U: F) f
- 4 W6 J# v# h. R8 ]2 ~+ l+ b
- #define LED4_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB
0 O% B0 F- H* E3 ` - #define LED4_GPIO GPIOB* r' P: Y3 M8 t* c& ~& M) ^
- #define LED4_GPIO_Pin GPIO_Pin_4
( c, p8 G* r/ g9 P# C - m) X9 S! f8 y6 B7 I; Z1 X
- /* Type definitions ----------------------------------------------------------*/
( z1 n' h$ B1 @/ }. c - typedef enum
D2 J$ ^6 j! c - {5 Q) `+ g3 o4 w6 R
- LED_Pin1 = 0,. E* J3 i9 ]4 L
- LED_Pin2 = 1,# ^( U: l, \9 i3 e4 E5 v
- LED_Pin3 = 2,9 m9 E7 P4 M" l- i
- LED_Pin4 = 3 @7 K# N+ l2 F$ N7 ]: W, w9 v
- }LED_Pin;
0 P7 T+ z! ?0 u7 v - * D' S, ]/ v+ z: s2 u1 L1 H( i
- typedef enum
, M1 ?4 f- D$ o2 L - {
4 P) h( I. o; Z: S7 }$ `( j - LED_Off = 0,
0 b" z, P4 J' L. I3 k3 o - LED_On = 14 O/ {3 p$ R4 t, w$ d/ {
- }LED_Status;
- J% G7 K V7 A6 X" w/ x @2 I
! x! P/ `# z( f% w5 }( `- /* Variable declarations -----------------------------------------------------*/
$ W9 i G Y& ^$ J7 ?+ [$ ` - /* Variable definitions ------------------------------------------------------*/" F% U5 g0 L% `/ n: n
- /* Function declarations -----------------------------------------------------*/# t# V( C( D* B1 a7 U2 z
- void LED_SetStatus(LED_Pin pin, LED_Status status);
, q. J( Y4 J1 p6 _2 \( r - LED_Status LED_GetStatus(LED_Pin pin);
" q- n) L: n: v$ d1 H
) w" Q7 o4 k6 ^0 Y i# v- [3 i- /* Function definitions ------------------------------------------------------*/
K3 C6 v) `0 w9 W+ @ - 7 ?9 u( O! }/ l
- #ifdef __cplusplus
" l! `& N- V# H - }0 S( I: t4 K! ~9 B6 {* ?
- #endif
& G+ J1 r8 Y; e6 n* e. S" e
( u W% \6 ?8 W" h7 p; x/ m. o- #endif /* __LED_H */3 }& U; s/ x$ O3 d1 [) z& |
复制代码 5 G( q8 E) ]* L" d) d
LED.c文件, t, z) ]( \3 V( R) W# Z
- /** a& P2 h. y- {& o$ e: o Y
- ******************************************************************************
; T' K0 E+ c0 X. _ - * @file LED.c4 y9 ^( F9 ]1 a+ U/ g' T- x8 e
- * @author XinLi
: V- _: q v, n& R6 d, u4 q! r - * @version v1.07 z8 H) y [5 X4 G4 v, A
- * @date 24-October-2017( q4 J6 n q0 Q* p/ {0 a7 N4 `# V
- * @brief LED module driver.( N# c8 I7 A3 I5 ?, U7 ^
- ******************************************************************************
" f' V' e2 z0 I# \1 z- g# G: _9 s1 c - * @attention& q0 T3 L+ L/ H/ X
- *) I3 m9 I' S5 j: `; O: I: q3 Z
- * <h2><center>Copyright © 2017 XinLi</center></h2>( A8 a7 O0 S$ i! M) f. W& m, E. j
- *- S- o, ^' R& Y1 a0 y
- * This program is free software: you can redistribute it and/or modify/ z* Y$ c! i" |% q
- * it under the terms of the GNU General Public License as published by) Q# @/ H, b; g! Y8 K! T& I
- * the Free Software Foundation, either version 3 of the License, or$ J) E# V ~9 I5 V+ M4 g
- * (at your option) any later version.
# H+ i) x6 u8 A5 g( }: S - ** R% i9 I. }' _; u, G6 u% g
- * This program is distributed in the hope that it will be useful,
1 d, v5 I" {3 I# u8 i" G7 Q - * but WITHOUT ANY WARRANTY; without even the implied warranty of
" I* n; ^5 `. X+ A. ^ - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the5 g6 O$ v6 H( P" n1 x6 V# G' V
- * GNU General Public License for more details.$ D% x' L) E/ A
- *
# b l) @6 u0 R2 F - * You should have received a copy of the GNU General Public License
2 \7 L7 r' C4 i7 V) m - * along with this program. If not, see <http://www.gnu.org/licenses/>.( O* [; t# {3 \
- *$ O3 C. v' u. T) _ m
- ******************************************************************************; o+ f4 O: ^$ t2 p/ c
- */
}. T; K: d2 r& _
' N2 A2 k6 u& Q3 {5 [ n9 L- /* Header includes -----------------------------------------------------------*/
+ K4 X; ?4 @/ B% r6 t& `4 A1 K - #include "LED.h"! Y: D5 A* g( @/ `6 E
- #include <stdbool.h>0 ~6 P% I5 c% L [0 R
# z( ]6 L# [# @' Z- /* Macro definitions ---------------------------------------------------------*// x8 |; ~2 `! f0 n( P1 y
- /* Type definitions ----------------------------------------------------------*/7 \$ `$ H8 O$ K0 q0 ]0 E: d: i
- /* Variable declarations -----------------------------------------------------*/
8 ~7 I9 V& b7 q+ o' v - /* Variable definitions ------------------------------------------------------*/2 }6 _# J1 E. y( c* t6 b8 Z- a5 E
- static GPIO_TypeDef *LED_GPIO[LEDn] = {LED1_GPIO, LED2_GPIO, LED3_GPIO, LED4_GPIO};
7 v0 H. I6 o: K" `( X8 q R/ N - static uint16_t LED_GPIO_Pin[LEDn] = {LED1_GPIO_Pin, LED2_GPIO_Pin, LED3_GPIO_Pin, LED4_GPIO_Pin};8 H( w- ]/ t& G8 j! F5 q/ W# ~
- static uint32_t LED_RCC_AHB1Periph_GPIO[LEDn] = {LED1_RCC_AHB1Periph_GPIO, LED2_RCC_AHB1Periph_GPIO, LED3_RCC_AHB1Periph_GPIO, LED4_RCC_AHB1Periph_GPIO};
3 I6 U( m& a3 r- n: D; R - static __IO LED_Status ledStatus[LEDn] = {LED_Off, LED_Off, LED_Off, LED_Off};' `4 M+ G4 F0 g; D' n9 F
6 b. x7 S# s! y0 ?8 @- /* Function declarations -----------------------------------------------------*/* b. [+ r6 j" Y* E' w/ {# n8 e
- static void LED_Init(void);0 {! v# h2 j& Q0 i# v
7 ^% Q1 b9 R7 S/ R- /* Function definitions ------------------------------------------------------*// s* e$ @7 q5 Y- y! h* ?
6 [! x- c' R0 \3 [- /**% `! D4 K# M: Q) }& }- E3 K2 Q6 B
- * @brief Led initializes.
$ C# j6 _; b+ U) B. n - * @param None.
/ N, p) \" h' d6 C$ m - * @return None.
8 e) ?4 t) x5 P3 S7 t - */
9 r- C( F" g6 j - static void LED_Init(void)
, w6 @0 D; t- ~1 Z - {9 [, A8 S0 Q, h! {- }
- static bool init_flag = false;% p4 {6 B! X. }9 N% S: k
-
+ k4 ^6 X" b2 h e6 H, |7 |/ V - if(init_flag == false)
. Y9 y0 m) {$ e. d8 H R4 ~ - {
; f3 y. ]& {( w6 c7 @1 G& ]$ Y5 ^ - init_flag = true;
+ H& F. ^, L' l2 A z -
% `" ]" g, Q9 r; y/ q% ? - for(int i = 0; i < LEDn; i++): d* i. E8 {' ^5 p$ d- z# a
- {
4 q1 H0 S/ y5 q" D - GPIO_InitTypeDef GPIO_InitStructure = {0};
- E4 L" V6 A9 }/ j -
( W& [# A% K- n, |% i7 i; F( e/ B - RCC_AHB1PeriphClockCmd(LED_RCC_AHB1Periph_GPIO[i], ENABLE);
* j: U+ N! k0 ]5 G - ) l }7 ^) I/ n# k
- GPIO_InitStructure.GPIO_Pin = LED_GPIO_Pin[i];
+ B0 L, u( P4 l - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;% Z0 }. N* u. I& a
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
( l' y5 T' d; s* z. @ - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
2 N5 l/ r) F& _ - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;6 e. b; T$ n* [7 A1 U% g) j/ @2 N( _" N
- GPIO_Init(LED_GPIO[i], &GPIO_InitStructure);9 c2 N% B1 k) N9 ?: ]% S) j
-
5 L9 q4 z! l; K - GPIO_WriteBit(LED_GPIO[i], LED_GPIO_Pin[i], (BitAction)LED_Off);
3 l# c1 {1 ~. k$ \. ` - }
* ~9 b% D8 o( }) }9 q) e1 k9 n - } ]2 ~' f( S. [! W4 Y
- }+ X9 C9 z$ K& W# O; K* f# {
- , Z- T6 y" v b& Q4 ^% M5 T" d
- /**- j3 V4 i( z* f( @- F
- * @brief Set led status.
y; j$ g) {) R - * @param [in] pin: That led.
; R, O% ^! y' ~+ C7 o/ W% z - * @param [in] status: Led status. L, ]% K) ]( P
- * @return None.6 M Z2 j6 G: x6 H
- */* D+ ?2 [7 p% p1 ^
- void LED_SetStatus(LED_Pin pin, LED_Status status)) i& q/ S0 T& e% }& {
- {
0 p9 {' K/ w" b! r7 G. u2 C Y8 @0 ^ - if(status != ledStatus[pin])
$ r B' a. N7 s1 X4 x& y" Z, O5 D - {
% \5 s) s: O* E5 b$ Z2 N1 E - ledStatus[pin] = status;
- q0 s" n: c3 S - 6 l, u6 _: O K' _! B
- LED_Init();
6 C6 u; O) J; ~* E - 5 \7 N! i& S. M
- GPIO_WriteBit(LED_GPIO[pin], LED_GPIO_Pin[pin], (BitAction)status);
% }' E" Y; F/ Z/ [) `1 x2 X* V - }
. E+ f) x4 I0 a& N - }
5 X* a+ R) o, T3 A - 3 @, V" w" ?6 f. {& d8 D
- /**
" V& u P& r9 E3 J" B - * @brief Get led status.3 M P: {0 U8 B, g& b* N6 e c R( f7 `
- * @param [in] pin: That led.! o5 u1 `1 ^. G& i3 c$ w, \; K; m6 h$ g
- * @return Led status.
3 U& s4 A& t0 N8 C9 U h - */
/ N$ @! ?% D4 x" D - LED_Status LED_GetStatus(LED_Pin pin)
3 J6 h( t8 S6 j1 Q - {: z" N; X9 H, c2 I7 n' ?7 f
- return ledStatus[pin];: h% S7 F1 y c( s7 g' I- u
- }
7 h% s3 H; l1 j; |- `8 q
复制代码
! Y6 h# ]# v( \$ r main.c文件
" q* w7 y9 t% r0 {2 {- /**6 i U. \$ u) Z9 J: n: {
- ******************************************************************************
& A7 m$ {$ L$ S) P M - * @file main.c
+ |4 y) d6 B4 A - * @author XinLi
: m) ~4 e% M' x% L. s - * @version v1.0: [: k7 w; h9 [2 E5 p" h" |8 k
- * @date 24-October-20172 z6 F1 a( h4 u5 X! `
- * @brief Main program body.
" t" i5 l1 h. j% Y6 u8 f& F - ******************************************************************************
. {4 j2 U2 }2 Y6 d - * @attention; y8 Z6 }. j- f0 N0 i! ?% |
- *) }0 P* Z5 W) Y) k1 Y* |% ]
- * <h2><center>Copyright © 2017 XinLi</center></h2>) J5 Q: e, y# n: t$ h/ H* n
- *
+ l# B7 y! O/ Z1 @ - * This program is free software: you can redistribute it and/or modify
0 P1 Z2 ?1 v% Y7 }/ L/ L - * it under the terms of the GNU General Public License as published by
7 {: l$ Z1 D1 f - * the Free Software Foundation, either version 3 of the License, or
, z6 X* w5 V1 _! g8 q - * (at your option) any later version.
5 a! p! h/ G' _' k: U6 Z& q - *2 ]( m1 o# b/ c; l8 i4 f$ j W1 l- @! n
- * This program is distributed in the hope that it will be useful,
d( [5 s* D. @) I: L- b* y4 D - * but WITHOUT ANY WARRANTY; without even the implied warranty of' R4 o6 r4 W$ l- T) o/ x
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
: v7 Q% L% G7 o/ D* ~ - * GNU General Public License for more details.+ f: v5 S( t& R$ K, ?
- */ y; T5 |8 @8 W# M3 y
- * You should have received a copy of the GNU General Public License
$ u$ s$ z: f* f- l7 O7 g) U9 g - * along with this program. If not, see <http://www.gnu.org/licenses/>.8 T9 `% w; M* f- Z
- *6 T3 s5 Z3 J( M7 r4 f
- ******************************************************************************; ]- N# H9 `5 Z# d4 w# [
- */
8 g/ O. `8 l1 K- k' Z0 w
3 n: a# N: e$ x$ J: P- /* Header includes -----------------------------------------------------------*/
' [6 `9 D& @8 l - #include "main.h"
! {" Y/ J# k2 {$ _: J& h0 h/ M - #include "Delay.h"! v( [$ a. C( D; z
- #include "LED.h"
+ O) |: M! R( R0 }, g% g& E3 a
, ~; A' K) ~+ F, q+ H4 w+ {6 V- /* Macro definitions ---------------------------------------------------------*/7 W( c6 n8 Y9 h9 Y
- /* Type definitions ----------------------------------------------------------*/
) T; ^. `8 l2 ?6 {1 _6 C; A - /* Variable declarations -----------------------------------------------------*/
7 [9 e7 [. Z" ?& \ - /* Variable definitions ------------------------------------------------------*/
% N6 V5 J. P) i3 X, c - /* Function declarations -----------------------------------------------------*/- ?1 V, Z$ u. E; b
- /* Function definitions ------------------------------------------------------*/- l! \3 X* T' b1 {# f
- " |7 c4 w% p+ h3 z
- /**' r' }& B. T9 Z9 c7 m
- * @brief Main program.4 K0 P4 e- N9 S
- * @param None.! d% ~2 {. W& o8 i
- * @return None.
' ]0 L' O$ i8 j0 l7 t# N - */: ?* k) g+ n. l {
- int main(void)7 K! I6 s7 k! I! t, T
- {1 ^* V8 L' P% f2 `
- for(;;)% `$ L' ~& d: G$ r. s" w
- {. w6 H# E' u- Q5 X6 \& q6 b
- Delay_ms(500);
( X( Q7 f+ @7 b - LED_SetStatus(LED_Pin1, LED_On);1 A& T) z; Y, c7 L; f( a8 L6 n
- Delay_ms(500);/ q* L3 K3 Z3 |/ ?$ f7 T3 d# W2 c
- LED_SetStatus(LED_Pin2, LED_On);
6 a& J& `* Z1 t4 a+ K3 H5 @ - Delay_ms(500);
: @$ t$ j4 ^ a) Y+ L# H! V _4 V - LED_SetStatus(LED_Pin1, LED_Off);' k' _6 R4 B' B* [5 q- L- B8 l% [" j
- Delay_ms(500);' n2 @$ t0 K* |/ S) j
- LED_SetStatus(LED_Pin2, LED_Off);
, J) V0 `5 t+ v8 t( T {# s - }
+ @. b) |3 e5 v- Q+ F5 e: R - }
" Z) u; ^+ [1 y8 D; f
复制代码
: w+ S8 R* \9 v: u$ Q. ~3,注意* R$ y* T- G1 [& ]- c# A
修改接口需要注意,LED的驱动方式和增减LED的个数。对应修改LED_Status枚举和源文件的变量定义。3 t B- i1 }1 D& W3 F- A2 f7 P
2 p% h! H/ O3 [, H1 g |