STM32F4(LED) GitHub仓库:http://github.com/XinLiGitHub/STM32F4xx_LED_Example
( H! f+ e% E' ]: F+ @PS:博文不再更新,后续更新会在GitHub仓库进行。9 s' g7 E3 I- ?1 Q* j
# i* x- ^% z6 c' }# {
' E& N* g$ x% Y" [& Y 在实际的项目开发过程中,常常会遇到硬件电路的修改,然后修改的部分就需要修改驱动程序。想这样需求该来该去是程序员们最烦闷的事情(重复劳动痛不欲生啊~)。为了避免或减少重复劳动,就需要在程序的架构上下功夫。接下来以最常见的LED驱动程序为例,进行程序结构设计。" ?; {7 b& x! q8 N: I. a1 z
# _# t5 Z8 p4 v* @9 P6 E/ y" F5 }1,开发环境
$ K! {4 b$ k' h, K: ]* @+ P8 B8 {4 b( Q$ n5 b7 Y& F- T$ i
1,固件库:STM32F4xx_DSP_StdPeriph_Lib_V1.8.01 n& M- U( }3 O5 d
2,编译器:ARMCC V5.068 [0 R7 l" k7 a/ p
3,IDE:Keil uVision5! ~7 C1 Z2 h( ?) M$ L
4,操作系统:Windows 10 专业版/ I) S0 l# h u) |3 F
( h7 j' x" A2 @( F, f2 w: ?
2 `7 V6 w. u$ u5 d
2,程序源码( s& ]' B; }) y$ m: f0 V! i& f
LED.h文件# ~. O) F. S/ c( n/ n
- /**
3 f- ~" ]; ^1 @- a - ******************************************************************************- y3 h, X4 W6 u/ z- \% H+ }
- * @file LED.h& O' Q+ ]9 F) [- v
- * @author XinLi8 P7 [4 |) Y! c& y2 x
- * @version v1.0* r' z( o# J: h7 e, L
- * @date 24-October-20171 f: B$ j% @% \4 | S4 f
- * @brief Header file for LED.c module.
5 s: w6 q% s) }5 a3 | - ******************************************************************************
; E8 Q0 y6 T9 O$ g# J - * @attention
) ~5 n& P# O7 f- i: s - *: k) C6 q% V8 b
- * <h2><center>Copyright © 2017 XinLi</center></h2>
( ]( b+ V2 M( K% |* a, { - *
* ^8 Q8 M/ r& V* s' F. ^ - * This program is free software: you can redistribute it and/or modify8 A7 i6 P# x1 y6 A
- * it under the terms of the GNU General Public License as published by8 C3 u/ [4 k9 B5 N# m
- * the Free Software Foundation, either version 3 of the License, or
+ t! ^! w0 e" e" v# L+ P% E1 ^ - * (at your option) any later version.! V8 Z# o+ y% }1 J
- *
- ^7 e6 Z7 [/ D0 G- X - * This program is distributed in the hope that it will be useful,
5 U, _! x+ \4 ^& S/ o' u- }5 g - * but WITHOUT ANY WARRANTY; without even the implied warranty of1 Z+ L% {( R9 K& Y3 U8 k O
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; S4 o& _! r! n, k - * GNU General Public License for more details.9 r p M& J0 Q6 D) q5 S
- *& C/ \# {8 u4 D% M/ E! |7 g
- * You should have received a copy of the GNU General Public License5 }0 o9 t: }* L/ g" H
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
; g( u/ d) x, y! m. q6 X+ o - *0 x* ^, W3 A; V0 F/ K/ U3 a% `% c
- ******************************************************************************
5 Z6 I7 h- c8 K) n# q' g - */
8 J: D$ ]1 @) R' a# q
9 d1 e$ ^/ H9 k! }& N) x- #ifndef __LED_H: ~$ I8 ?& o# { m( F4 ~
- #define __LED_H
7 G, B6 m% T: L: j
5 V; ?+ A9 J5 y/ N- #ifdef __cplusplus
7 [% d5 x! t# A( N- O3 n - extern "C" {4 N8 {+ Q2 C* ^1 L% x
- #endif ~, t# i5 w. x8 o! ]
- Z% y2 _. j F _5 H- /* Header includes -----------------------------------------------------------*/
{$ a! N, t& d, X& V! n5 V - #include "stm32f4xx.h"
9 N4 Y/ f% R d" l7 H) m) g, R - 9 y \# r- r1 B4 a. I" b$ U
- /* Macro definitions ---------------------------------------------------------*/
% U+ c4 ]$ a; g& Q$ u: C+ X - #define LEDn (4)& g1 a9 k1 y0 \) N8 K
- 8 M+ c0 {" N2 q8 _" n) \
- #define LED1_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOC( d& F' O @3 G+ C; I9 l5 W1 h
- #define LED1_GPIO GPIOC* Q4 H7 m1 W& Z( _( ]
- #define LED1_GPIO_Pin GPIO_Pin_0
( H' m; X! A5 }8 u7 e
! r. L# c2 x0 V O! H# Q7 ^7 A9 ]- #define LED2_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOC
$ o, G1 u% G4 S. h! j - #define LED2_GPIO GPIOC: J7 V1 p, d& n7 a& l4 ~
- #define LED2_GPIO_Pin GPIO_Pin_1
, N5 Y- E, `9 z) C
- q: Y% q! s& `0 B: ?, W- #define LED3_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB* b+ `' L. n$ G( S1 S, o
- #define LED3_GPIO GPIOB
' Y$ i. W% o8 l2 f8 @1 |9 w - #define LED3_GPIO_Pin GPIO_Pin_3
# ?. k! g! p8 }7 l W+ D4 g2 M - % @! P; N) T3 j. v, p9 k" \
- #define LED4_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB2 L7 j# P$ G0 O8 B3 b
- #define LED4_GPIO GPIOB
9 y, q6 T# c4 }) |4 ^4 c - #define LED4_GPIO_Pin GPIO_Pin_4
, E8 x5 u( _( X' J5 i9 j
; h9 O" K( m( v4 v/ V9 [- /* Type definitions ----------------------------------------------------------*/1 Z' d8 M0 U! K. ] U
- typedef enum
' l! ^( A+ q5 O( s) }' ? - {
7 d, w4 I. B- w& q: A2 N7 i+ r3 [1 ] - LED_Pin1 = 0,. E3 f" T( U% m$ X7 w
- LED_Pin2 = 1,7 f, y, q0 c l1 T4 p
- LED_Pin3 = 2,: z' Q- }9 q8 Z" u+ E4 u$ q) V
- LED_Pin4 = 3) F. ^7 G5 Y- Y" h' n7 k5 h4 r: h
- }LED_Pin;: w3 F! @7 t2 H# v q% f G
- : T5 V/ i0 k2 c5 q8 W
- typedef enum/ @; d* t+ _9 w" X! Q
- {1 t1 X$ g. s8 N9 T( {
- LED_Off = 0,
0 D( C# g3 h/ A4 R4 [* x - LED_On = 1
: k! Q; Q* a6 T/ b1 Z- \ - }LED_Status;
9 f+ B! e1 B) Z8 v, W
y: @& Y8 ~/ h" W8 S2 Z7 C y- /* Variable declarations -----------------------------------------------------*/8 k! |" P) H: f, o1 V
- /* Variable definitions ------------------------------------------------------*/$ N8 P6 X- Q0 }0 K; \/ V7 `: i
- /* Function declarations -----------------------------------------------------*/9 Y% z8 a: z9 I
- void LED_SetStatus(LED_Pin pin, LED_Status status);8 r5 M R/ ?3 i* \
- LED_Status LED_GetStatus(LED_Pin pin);
1 `% I' `0 i) G
% r* c' q8 z/ u6 {8 S R3 I/ Z- /* Function definitions ------------------------------------------------------*/7 U' A' j5 {) r$ o
) R1 Q' |. M% G' _# J- #ifdef __cplusplus
% v1 T2 X3 k; y d7 u - }
4 `) P" f; J0 W8 n# |+ @% f% o& y - #endif
( W: T+ w3 X' L! D - ( e9 L% q1 g0 `* _( b9 q: v9 \8 j
- #endif /* __LED_H */ O) Q. M( A* U. V
复制代码
; `# c1 T( i2 c8 U: O LED.c文件; F# p0 ?4 x" V& O7 @% Y! r
- /**
) O* W Q5 e; |7 x" ~( X! y% P4 s; C# c! B- q - ******************************************************************************
% y7 c8 j' w. d" L) {$ G$ g t - * @file LED.c
$ k& L1 @0 s9 z9 m9 E2 U. Y - * @author XinLi
* ~, K9 S+ a# l2 m1 Q1 @* E - * @version v1.0
5 O0 s0 J' ~1 Z, ^1 r4 } - * @date 24-October-20177 h, G$ j2 N5 e8 b# z5 t
- * @brief LED module driver.: C( `+ c2 K# \" _7 T
- ******************************************************************************* r' T R, J: ]7 T c5 g; F8 y0 R4 m* v
- * @attention+ N s, w; o0 R% Q. e7 T7 V
- *+ h, W z( ` }+ M6 B- C
- * <h2><center>Copyright © 2017 XinLi</center></h2>/ C! v, x) z3 F2 C7 u; `) g
- *
/ L, | R1 W) }, r - * This program is free software: you can redistribute it and/or modify
}! w, L& K( M8 x! q, D - * it under the terms of the GNU General Public License as published by: v# Q! a3 Z c9 O, q9 }
- * the Free Software Foundation, either version 3 of the License, or
' M1 ]4 u0 F, F# L' P$ v/ \# c! y - * (at your option) any later version.% Y2 e0 [2 _8 |; F+ x% I
- *
) c0 {% l: @/ X f4 K - * This program is distributed in the hope that it will be useful,
3 _3 K* o# L# K9 X0 U$ v - * but WITHOUT ANY WARRANTY; without even the implied warranty of0 X9 N% q% o* n0 o
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1 A& }! I: e2 r. k2 E; i - * GNU General Public License for more details.( p0 I; w6 ]) E3 P: T1 S3 o
- *
7 i+ z7 [) i) i; V+ N" F6 c - * You should have received a copy of the GNU General Public License2 _8 R4 ]; ]. V; J- ]. g9 @
- * along with this program. If not, see <http://www.gnu.org/licenses/>.9 B8 |8 d* x! I% m/ {: [" @, k
- *% f/ [. g0 Y. P( z9 }; s: A
- ******************************************************************************
/ D6 ^9 D. t0 W& n1 V: @' ^1 m9 V - */
; f/ K$ x# w) S" e5 o5 U* k% Y$ D
# K# g/ p8 S0 B+ b( C5 v' n- /* Header includes -----------------------------------------------------------*/
! I8 i4 N* q8 i: x' M0 m - #include "LED.h"
8 f1 e v$ f, P# B - #include <stdbool.h>
! A b$ a$ O" o2 z0 d6 ]! R" ~% I) ^# U
+ R \$ i# E" w+ z+ A2 n. ?( e- /* Macro definitions ---------------------------------------------------------*/# B& l* X( y" `8 i6 q! V
- /* Type definitions ----------------------------------------------------------*/, o# \( o6 A2 _$ g/ }1 a6 ^
- /* Variable declarations -----------------------------------------------------*/ L2 |, c& H& Y5 y" H
- /* Variable definitions ------------------------------------------------------*/
! G9 ]: z9 F0 G3 N - static GPIO_TypeDef *LED_GPIO[LEDn] = {LED1_GPIO, LED2_GPIO, LED3_GPIO, LED4_GPIO};
5 E3 E, T. `9 j5 N, F9 K( F. T6 p1 ? - static uint16_t LED_GPIO_Pin[LEDn] = {LED1_GPIO_Pin, LED2_GPIO_Pin, LED3_GPIO_Pin, LED4_GPIO_Pin};+ z8 S$ W' \: R% Q
- static uint32_t LED_RCC_AHB1Periph_GPIO[LEDn] = {LED1_RCC_AHB1Periph_GPIO, LED2_RCC_AHB1Periph_GPIO, LED3_RCC_AHB1Periph_GPIO, LED4_RCC_AHB1Periph_GPIO};+ G" r$ @0 q. ?% P6 f& }
- static __IO LED_Status ledStatus[LEDn] = {LED_Off, LED_Off, LED_Off, LED_Off};- J% }7 U8 v O* s
- ' D5 @, D0 |$ [3 m; g& Z
- /* Function declarations -----------------------------------------------------*/2 j* F1 y) w, k1 X
- static void LED_Init(void);
5 J# E2 a1 J+ d
2 h. f$ u+ M) J+ J7 N- /* Function definitions ------------------------------------------------------*/
2 T+ C4 B0 c0 x- S
5 h- \- ^- e' q5 P# i- /**
" f' J& l0 s: ]- x( |$ x - * @brief Led initializes.4 A: _ z5 ]' g i( I4 K
- * @param None.8 ^% S" p( X1 k( h1 V
- * @return None.
: D+ }4 c+ i3 c) L - *// d' ^0 H% ^, [) v7 [$ q
- static void LED_Init(void)* z- N- S9 Z; Y1 ^
- {! i) b/ Y# Z7 ~, r- [" z7 f
- static bool init_flag = false;
4 M2 [# r/ s3 H/ p; I- A - . L9 O; |- C8 K8 o: A$ @) {8 H a, ?
- if(init_flag == false)
/ j* B" E3 F2 q" F - {
' T4 q" O& t9 }0 ?: x1 j* V - init_flag = true;
/ X- Q/ V9 Z) n3 C2 J' A: @ - 1 ^. I* q. b3 ] @8 h2 [4 D
- for(int i = 0; i < LEDn; i++)
7 R' X+ v/ W' M* {! ]% V k5 B - {) k9 j* r, g1 @9 l( t9 g- v/ k
- GPIO_InitTypeDef GPIO_InitStructure = {0};
" z9 ^& T _& [6 u4 g6 ] -
0 H6 \* g9 K ?. j' | - RCC_AHB1PeriphClockCmd(LED_RCC_AHB1Periph_GPIO[i], ENABLE);+ w5 w2 `' Z! n; J
- j1 J, p5 L/ \% q1 z
- GPIO_InitStructure.GPIO_Pin = LED_GPIO_Pin[i];% r, p/ ?) o; p8 M5 L- o& M/ C. V2 d
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
9 k5 B% k0 W! C+ ? - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;3 H9 P) ~$ N' R* F
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;5 l! V5 c+ Z1 P" W5 ]
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;; v/ ]& f' ?8 y) n" X9 ^+ \
- GPIO_Init(LED_GPIO[i], &GPIO_InitStructure);: Q% _5 c) J+ q6 a0 Z4 u
-
$ n9 c* s/ N. b2 C/ T - GPIO_WriteBit(LED_GPIO[i], LED_GPIO_Pin[i], (BitAction)LED_Off);
: L! F& Q: e# l. M; r& n/ _% f - }+ Z5 ]$ H3 F$ ?* r* c: P
- }: M$ t4 ]( L3 E+ w8 ~
- }
: `4 e1 y/ a1 N7 N- _1 n8 J
! q2 _2 u0 ^. a3 `, L- /**$ ~$ p9 E0 E7 ?8 P- J; F
- * @brief Set led status." z- D* @6 W# Y4 g6 H) E8 }, I
- * @param [in] pin: That led.' R/ F8 [/ W, F; N2 E/ ^( U
- * @param [in] status: Led status.
1 d4 Z% Q8 q- b1 n - * @return None.
p5 |- r6 \, v6 X$ u - */4 q! V5 `) I. M+ `5 W6 ]4 l9 a
- void LED_SetStatus(LED_Pin pin, LED_Status status)
$ N% i+ \' p* j) R6 S/ B - {# j: x1 _8 y$ O
- if(status != ledStatus[pin])& T/ ~- t p% \. x
- {3 a' U8 M& w% A) e
- ledStatus[pin] = status;
; J j' G: W1 q/ \' t - : \) W$ e+ ~% n5 o; R: R# M4 H
- LED_Init();
/ I2 d: v1 i0 { -
' h# I1 g! M6 q, [/ H: B - GPIO_WriteBit(LED_GPIO[pin], LED_GPIO_Pin[pin], (BitAction)status);- a- F: F% Z; x5 G1 w5 h
- }( C, e" i0 w8 u; R8 W
- }) Y w. U" Y d d
0 K: B8 f% \! o0 H8 }- /**
4 g$ Y, b. x+ g1 R - * @brief Get led status.6 V G# u& {6 l) O8 ^
- * @param [in] pin: That led.
! w3 U9 h. D) ^; U6 [ - * @return Led status.& @0 S; X6 Z9 O( J5 D9 }5 T9 m
- */
& F+ [& `3 R. q7 h6 ?4 ?0 N1 ^$ B, }1 B: d - LED_Status LED_GetStatus(LED_Pin pin)0 t4 n# S' H3 l4 D# d) I5 Q3 z
- {2 n0 m. ?" |7 p% ^' S( f. a0 L
- return ledStatus[pin];
. j- L* v- D( C: I - }
9 h7 b7 V3 D2 B5 o. ^
复制代码
' b. B) ~3 q: C6 e/ @% o main.c文件
3 H' A& g9 n2 l3 S- /**
* k5 t# G9 M* p: x! f5 q - ******************************************************************************: G4 \. }+ q- `6 ?( M/ ]3 H
- * @file main.c% A9 b7 U4 W- @ S: p9 p
- * @author XinLi; {; j7 F- F# j# `
- * @version v1.0
- a- H, Z0 ^% k9 `* t! w" O { - * @date 24-October-20175 W: A) N# f! _( C& f
- * @brief Main program body.
7 j6 t2 k G8 X7 i/ s - ******************************************************************************( M G# d, }9 L- K
- * @attention
/ V5 M3 f9 r& Y) R$ F" s7 G - *
, }7 ~" H" w, ]- T6 b4 M - * <h2><center>Copyright © 2017 XinLi</center></h2># p- i- g1 {2 G, |& I
- *
4 n- B5 y' p, e% ?% S - * This program is free software: you can redistribute it and/or modify
9 e& y& C6 A' p/ D7 c - * it under the terms of the GNU General Public License as published by. [# K( R) r" r% ?1 I" i! }7 l* k B
- * the Free Software Foundation, either version 3 of the License, or
6 H/ o. n2 U$ f5 H4 H3 q/ B* R! ? - * (at your option) any later version.3 H1 A! F4 w. l1 q
- */ M; V1 h, D8 q% |7 I: M! R9 `
- * This program is distributed in the hope that it will be useful,
' S6 g$ n% W% f& F# n - * but WITHOUT ANY WARRANTY; without even the implied warranty of: P- G2 ]* R: ~6 B7 L4 O- i
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5 H( S* H7 B8 _4 L" ]+ ] - * GNU General Public License for more details.
~3 m; m% ~' d, L- v9 q- M* b- t - *
" |8 \% g% t! U* X5 s& R - * You should have received a copy of the GNU General Public License& z( V) w' _8 J: \( `* \% {- L+ c
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
* r( q" t; L# e4 h* |+ k% R! @ - *3 k4 M! ] b4 o. h$ C- K9 h. m6 g4 Z
- ******************************************************************************
q; @- _: z2 ^3 r4 A: o - */
9 Q7 r$ d) i) n1 b
% }- B6 X. U. S; l5 [; y; f- /* Header includes -----------------------------------------------------------*/
; }2 o* G! T; Y$ Z" q - #include "main.h"
" B1 C" S$ O/ A @ - #include "Delay.h"5 h# F" p+ [. |! n' c2 W" U) s
- #include "LED.h"
2 L- v0 h- ]. N: `! H
9 _, B s0 L B' i- /* Macro definitions ---------------------------------------------------------*/
& B/ M# q" A( f - /* Type definitions ----------------------------------------------------------*/! a6 U4 k8 S5 |. J4 p
- /* Variable declarations -----------------------------------------------------*/: s* N) X4 x" p; n
- /* Variable definitions ------------------------------------------------------*/, \/ `' d$ t+ E
- /* Function declarations -----------------------------------------------------*/+ A+ L' D! ~* }
- /* Function definitions ------------------------------------------------------*/2 ]- j$ i) z/ n, v
3 V. J& z. }& K( d# s7 Y% z- /**
/ v0 b9 j$ K9 Y3 _) `+ ^ - * @brief Main program., [5 E$ j- |- H* x: R
- * @param None., A |4 [9 m$ U$ A% o' ^# y
- * @return None.
`5 T8 u! U% l1 C7 V# P - */
0 D+ ?0 Y3 E: S- M4 J - int main(void)( u+ C) @3 |+ a3 i; |
- {8 |, o6 Z( o) }
- for(;;)+ Y1 t9 U' J/ s% x( D$ ^
- {9 [+ v% C+ f) D1 j% O: D/ c* ]
- Delay_ms(500);, E, J+ E/ b# ?
- LED_SetStatus(LED_Pin1, LED_On);: H# `+ B4 _* g5 P
- Delay_ms(500);
4 u6 B2 H, G# ?: S' m8 R - LED_SetStatus(LED_Pin2, LED_On);, w! K; P- I( C. v {
- Delay_ms(500);" S8 x. A3 P, n5 V2 ]; [: I0 e
- LED_SetStatus(LED_Pin1, LED_Off);3 o3 l2 D0 S1 ~3 j V
- Delay_ms(500);
& @- f% o. ~4 G+ D u - LED_SetStatus(LED_Pin2, LED_Off);
) ~8 j& Z& T4 M, G; H) [( X - }
3 i' C/ z. F2 X6 d6 e/ o - }
1 K8 @4 E2 O( v3 @+ I; y
复制代码
" m& s/ i. p! y8 Y$ ^1 T: s3,注意
! p0 ^; s( t6 J0 Q6 k4 T/ m4 n 修改接口需要注意,LED的驱动方式和增减LED的个数。对应修改LED_Status枚举和源文件的变量定义。0 b1 S! i) ~* S
5 n: r% W" q: D, T" l( X' t |