STM32F4(LED) GitHub仓库:http://github.com/XinLiGitHub/STM32F4xx_LED_Example
- v1 j; G6 _; g2 H; ]PS:博文不再更新,后续更新会在GitHub仓库进行。( B: y7 }: v1 ^ I
1 H& k$ F6 `/ e5 z
+ D9 ^# D2 t0 a: O: l9 G
在实际的项目开发过程中,常常会遇到硬件电路的修改,然后修改的部分就需要修改驱动程序。想这样需求该来该去是程序员们最烦闷的事情(重复劳动痛不欲生啊~)。为了避免或减少重复劳动,就需要在程序的架构上下功夫。接下来以最常见的LED驱动程序为例,进行程序结构设计。- M% P% {% G# Q s4 S- O, t: B
* i' R7 C5 U- A" |3 C1,开发环境
8 I" g1 P8 B4 ?
5 G5 `1 p* M+ Q0 A9 e3 r 1,固件库:STM32F4xx_DSP_StdPeriph_Lib_V1.8.07 [- Y8 ?, A" K1 t$ `
2,编译器:ARMCC V5.06! G! C N4 H6 A9 A4 j2 P5 g W
3,IDE:Keil uVision57 w3 @3 k/ |( A& R, O: L5 t: ^
4,操作系统:Windows 10 专业版' y; C3 n- ?* Y* Y( i% g
4 X6 Y3 J9 R( l5 `7 V% |( E; {
. w+ _3 |% ?. c9 Y: \! H( _
2,程序源码
' |9 |2 K9 z. {0 k% ]$ t9 N/ e LED.h文件
* Q9 C4 j# e: _. x- p7 k8 {- /**3 i u9 [0 p/ h2 H% y
- ******************************************************************************& G, B/ Q T n& X8 d
- * @file LED.h
) K" l$ k% c( }) b l: w - * @author XinLi9 F: \& e6 L+ U( Y4 u* K
- * @version v1.0 b# R, t" ^9 c( k" A
- * @date 24-October-2017! y8 R l* y3 A
- * @brief Header file for LED.c module.
% `0 N7 v. _0 A! ~9 T. ^6 o v - ******************************************************************************. P/ A% g. a- G" G- p6 f+ s
- * @attention
% o; _( T; |! x4 g( h2 f: D - *- O% ^, q( F$ F; j2 j( V# b
- * <h2><center>Copyright © 2017 XinLi</center></h2>
6 C Y: P3 n& i, |3 o: C/ { - *
! R, a# A* _( T4 \ - * This program is free software: you can redistribute it and/or modify7 @5 w4 w1 s# S: h
- * it under the terms of the GNU General Public License as published by
$ o" ]# K+ N" H' h, ^ @/ F# r5 O - * the Free Software Foundation, either version 3 of the License, or$ |; c I+ J/ K+ p% C F
- * (at your option) any later version.
- J; u% D6 a! A2 Y! b - *2 w+ m! ?4 y9 P$ G
- * This program is distributed in the hope that it will be useful,
3 _6 c4 Q5 U, a( U8 l a" M/ c - * but WITHOUT ANY WARRANTY; without even the implied warranty of
0 g6 p/ m* h) L' ^) T5 ` - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" v4 Q x2 f- L' p9 Y0 |4 s& D - * GNU General Public License for more details.
7 G& G. ~4 f# N1 Y5 h* v- E - *% X% Z7 s! C. W6 I a
- * You should have received a copy of the GNU General Public License6 x! F) H5 J3 o p
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
" ^& s; n: H/ J# Q" Y4 N* n' C" } i - *5 Y( F1 O [6 Q9 ^6 N% _# o) L
- ******************************************************************************
# {4 J7 X5 h% [) k - */
2 {* S/ m. l! ^8 Z8 e
% ^& n* ?) l6 q; @$ H' Z" E; _1 s- #ifndef __LED_H% H- S0 l$ w1 v- e
- #define __LED_H7 e- l" B4 l2 R. F
- 4 g4 d4 y: E, A t8 v, Q
- #ifdef __cplusplus
( T" o1 d; Y1 c M( b3 W - extern "C" {0 {2 @$ k9 {2 Y' H; o F0 q" b
- #endif3 P: H$ {/ n9 q: x% f$ I2 S+ x
- 1 `) [1 ?$ y& W/ a- a
- /* Header includes -----------------------------------------------------------*/
, F6 x8 j& E& |+ g3 a0 F9 ~ - #include "stm32f4xx.h"
0 z. ~8 g) T9 p! e - ) U, U% h( \3 _
- /* Macro definitions ---------------------------------------------------------*/
- g) ^7 i: ^9 P) T4 Z% l- j - #define LEDn (4)
8 J* T( O7 i4 u# h9 J4 k0 F - \1 w0 K/ V* i
- #define LED1_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOC0 ~/ ]4 p2 R; l( E
- #define LED1_GPIO GPIOC& D& o. | P" l- U2 H6 r$ g: e0 r3 s
- #define LED1_GPIO_Pin GPIO_Pin_0' e6 p. p: }7 \4 s" d/ s( }
! i1 O6 @% m9 w9 h: g2 p- #define LED2_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOC
$ H) \6 h6 }7 C - #define LED2_GPIO GPIOC2 v( o3 c5 @5 ?/ `; G" l- P
- #define LED2_GPIO_Pin GPIO_Pin_1
2 Y8 z* W3 `# Q4 n! f& K3 S - ! |: {- x0 x6 y- B6 x& R5 z
- #define LED3_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB+ m, R, v" d0 H& D5 d; G
- #define LED3_GPIO GPIOB
- z* _, H1 ]& \3 o, W - #define LED3_GPIO_Pin GPIO_Pin_3
( }% y4 U+ ~; V/ `9 X Q! P - & F+ a/ I7 L( u& x1 U8 x, u
- #define LED4_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOB" v7 t5 t! O2 X8 |% M
- #define LED4_GPIO GPIOB: f, v6 |# ]; D, f" a
- #define LED4_GPIO_Pin GPIO_Pin_42 Z/ `& a# B% U, g3 t3 ]) @2 G5 U
- ! S4 s* J# ]; l2 Z9 r! \
- /* Type definitions ----------------------------------------------------------*/! T* Q. D6 R& t; l
- typedef enum
3 y, B6 [. ~: f/ r; Z - {
8 L' c0 L: x# ~( |( A+ N/ V - LED_Pin1 = 0,
! W! j6 F% ?$ p+ k9 l9 r - LED_Pin2 = 1,
v/ b9 u4 C9 z# B) E8 d, [ - LED_Pin3 = 2,* J6 {3 l7 F: G0 Y' j4 z' k* X
- LED_Pin4 = 3
! O$ i4 ^% w! y, t$ F: x - }LED_Pin;( k6 T" ]9 \4 o
- ; J, J1 y1 X) |% ~5 m# j
- typedef enum
& ^3 H: R8 _! |' I5 n( @ - {
7 l( u9 Y( p \- {2 n - LED_Off = 0,& b2 g8 v& O- L" K7 L
- LED_On = 1
" E* F0 s0 n4 X0 c - }LED_Status;7 i- ]# z# K+ y9 u' K" n
r+ C3 X e( Q6 `, n5 c( j- /* Variable declarations -----------------------------------------------------*/
, t$ ]: s6 V( b" j6 X e - /* Variable definitions ------------------------------------------------------*/$ k" f2 h$ G A* @+ X- _- Z
- /* Function declarations -----------------------------------------------------*/
( }( F4 n2 }. q4 R; c0 b$ V - void LED_SetStatus(LED_Pin pin, LED_Status status);
% T! _1 K% }$ c- @+ q - LED_Status LED_GetStatus(LED_Pin pin);
& C7 {" G& m! V% d* V* T7 H5 i0 W& y - # f, d; B9 z9 U! y6 X
- /* Function definitions ------------------------------------------------------*/
8 k- b1 {4 ~* v" W
3 N3 v7 A2 C5 p- y- #ifdef __cplusplus
. q9 H% m+ x$ i( O0 R8 k - }9 L& x3 q: z/ a) u/ \ n: U! o
- #endif
7 ?5 M- q: \9 i5 g
4 n; i) \4 S7 R' i Z, h# e- #endif /* __LED_H */
/ [: @% ?: S6 H; n0 W
复制代码
0 v& L+ L8 ^& \: g- Y; i; N7 A LED.c文件
A; ~ w, d1 N/ [- /**( ]1 b, L$ F: G+ u8 L
- ******************************************************************************
3 `' b i( u$ P2 M+ x - * @file LED.c
0 O; @* ?' j" I7 F. _2 Q* C1 O - * @author XinLi
) Z" Y/ I ]; i# ~ - * @version v1.00 O A1 F; c5 N: t; k7 e$ E
- * @date 24-October-2017
, H" H( h& h' t n# Y - * @brief LED module driver.
5 B$ O, [" Z8 W9 r# G" O: F, d - ******************************************************************************
5 c: I5 X, t( h3 d% W# a9 q" D - * @attention
9 I# v. ^8 K" j$ J+ a - *
- r$ p7 f; H- M8 k8 U - * <h2><center>Copyright © 2017 XinLi</center></h2>. J1 R: M1 o% N
- *- E) y+ }4 l+ f! Q8 Z6 z, o' B6 |- ^
- * This program is free software: you can redistribute it and/or modify
* ?; \3 k' c9 b% w& V) g9 A* \ - * it under the terms of the GNU General Public License as published by
8 c6 u3 N0 O' X1 o- m - * the Free Software Foundation, either version 3 of the License, or1 \; |5 J8 e, M, F- x, d% { N' Q) _
- * (at your option) any later version.
9 d) |9 `0 X6 i1 S x - *( Q6 h6 u( W7 U( v8 L, ]
- * This program is distributed in the hope that it will be useful,, J2 K* ?. Q& }0 k
- * but WITHOUT ANY WARRANTY; without even the implied warranty of$ L9 t1 K ~' s5 j' G3 j& M
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the% c% i; q4 H* c' J6 v' n5 v
- * GNU General Public License for more details.6 @) i" p b: k( n, q
- *
6 l; H" l m7 y% v/ v4 W - * You should have received a copy of the GNU General Public License
0 Z% T# v5 X9 G - * along with this program. If not, see <http://www.gnu.org/licenses/>.$ s- p \3 I7 w
- *3 I+ U8 M ^5 k* ]6 Y3 N6 v
- ******************************************************************************
& V9 @% N+ X) z7 F: H - */
9 d# o( _3 r$ j4 c0 |8 G( ] - k% F* { \1 X( L# c
- /* Header includes -----------------------------------------------------------*/
( n- _/ v' }+ l4 P1 N - #include "LED.h"9 i% I H f; F# I* \4 N
- #include <stdbool.h>/ H$ y; Q0 `) D. r* Z
- 1 f; ]7 | W6 K3 `. C
- /* Macro definitions ---------------------------------------------------------*/# w! g/ i2 v/ h. G6 V
- /* Type definitions ----------------------------------------------------------*/5 J; [ c6 Q* [2 O/ r2 a" ?
- /* Variable declarations -----------------------------------------------------*/, `$ R. g: `8 v$ ? y
- /* Variable definitions ------------------------------------------------------*/0 v+ V, S) p2 r" d- P
- static GPIO_TypeDef *LED_GPIO[LEDn] = {LED1_GPIO, LED2_GPIO, LED3_GPIO, LED4_GPIO};
3 M, Y; e; n( ~1 y& x. C - static uint16_t LED_GPIO_Pin[LEDn] = {LED1_GPIO_Pin, LED2_GPIO_Pin, LED3_GPIO_Pin, LED4_GPIO_Pin};
9 j, \* g) G: `. |5 B - static uint32_t LED_RCC_AHB1Periph_GPIO[LEDn] = {LED1_RCC_AHB1Periph_GPIO, LED2_RCC_AHB1Periph_GPIO, LED3_RCC_AHB1Periph_GPIO, LED4_RCC_AHB1Periph_GPIO};
% r# U0 [/ Y8 ^; x1 \) o/ [' W - static __IO LED_Status ledStatus[LEDn] = {LED_Off, LED_Off, LED_Off, LED_Off};/ B9 t4 v. O+ t3 ?
' d6 q' l; P- H8 J J- /* Function declarations -----------------------------------------------------*/5 [7 I( Q6 _$ K# @
- static void LED_Init(void);! _. ^8 S. o9 |/ f8 E% c' p! B/ F
6 O4 s. @' o) Q; A+ J& i- /* Function definitions ------------------------------------------------------*/+ F5 d( q4 c- R% O, x- f
3 {3 n: l8 ]' E7 H8 A/ H; ]4 l- /**. @) T6 l+ _# {5 M. T6 R6 Y
- * @brief Led initializes.
) N$ M; a$ J; J0 d* d - * @param None.9 @! z. ]. Y4 W; y" l/ E5 r, a/ W L
- * @return None.
+ n% m# A f% n/ @3 X8 I* _3 J - */ Z8 v2 ?% j) b# c0 w D+ i( Q2 t
- static void LED_Init(void)/ v" J* W; x! W, z
- {
9 F6 n+ G% F$ v& J! R' } - static bool init_flag = false;, `7 ?! P7 X( I2 M
-
2 d# _$ O E( o: U& ?$ R - if(init_flag == false)
& x( S' X2 D% W& V. m - {" K- E- E, Q4 r1 x4 G
- init_flag = true;* {! a' x, M6 D4 }
-
1 G: }! M0 G: A ^ - for(int i = 0; i < LEDn; i++)
) n6 e) q/ t8 s, T7 T - {" y( N+ s$ ^( K/ T) J1 r1 U
- GPIO_InitTypeDef GPIO_InitStructure = {0};* `1 U* L9 ~) V7 R$ N6 T
-
! m* E2 _( W* p/ `2 y7 B3 S - RCC_AHB1PeriphClockCmd(LED_RCC_AHB1Periph_GPIO[i], ENABLE);; o) _, Z- p; b- U% p
- 7 N( A% P a$ F; [8 @2 M8 u/ x' Q
- GPIO_InitStructure.GPIO_Pin = LED_GPIO_Pin[i];1 z& l5 E7 V6 _& I: ~3 F
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;8 D J) q/ I) O8 h5 B4 A5 c' X
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
8 N- R* n" o" s+ n2 ?* g( K* \ - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
" p( e$ u2 L. W% w. U - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;: r* l: Q8 y' ]0 `
- GPIO_Init(LED_GPIO[i], &GPIO_InitStructure);
6 V' O3 q: Y' }- G- Y" K - , w% {8 l+ `( n4 ^2 @
- GPIO_WriteBit(LED_GPIO[i], LED_GPIO_Pin[i], (BitAction)LED_Off);
- T( U1 Y6 t! i( p5 W7 K - }6 W( X* y8 i5 w
- }
8 K* C8 @; \: k - } G0 a9 C* I- i0 g% l, L
& v1 T( H0 x5 ~- /**( p) V9 A8 F* q$ V8 B
- * @brief Set led status.
: c9 U% r: K& [3 ]4 m- B& E' y - * @param [in] pin: That led.
3 e5 u( N$ u) j; a& @8 c/ |& G# s - * @param [in] status: Led status.
9 z1 S5 l5 F; h' _0 x - * @return None." i& X. a& F) y( ]% X' L
- */
3 t. @2 V% v" O% V; O5 K) P - void LED_SetStatus(LED_Pin pin, LED_Status status)3 K4 P1 l% J9 i5 V
- {3 F. I- G0 r7 }" L* F7 n
- if(status != ledStatus[pin])) h2 U1 q% N& l5 z" W; Y
- {
2 a3 U# X/ _" o - ledStatus[pin] = status;
}) H7 @3 e8 x" p0 L2 x - ; g+ z6 A, O& z% o/ D( F9 O
- LED_Init();
) u! I; d# O% s- B5 k -
( O7 d- n2 J/ g: B( K - GPIO_WriteBit(LED_GPIO[pin], LED_GPIO_Pin[pin], (BitAction)status);
1 t. r1 x, ^5 O+ P, n7 [! | - }
$ ?, r/ q) L$ m* q3 W - }
. j/ S9 H6 Z5 |, e
0 g7 ?5 n7 Y) m. J. S- /**
; R. f T1 A9 N" h: ? a - * @brief Get led status.
$ z h7 Q$ i- Y0 f! X- f - * @param [in] pin: That led.& k2 h7 n3 C: F
- * @return Led status.: }9 w% Z% H$ _, m
- */8 c6 C s$ ?6 R9 e0 F# I3 k7 Z
- LED_Status LED_GetStatus(LED_Pin pin)
- i' Y5 z8 _: \/ {: l7 g - {7 ~9 t. O" p% `* Z: r9 D
- return ledStatus[pin];0 K9 B5 W( j+ T, z1 @3 [
- }) i. e2 Z4 L/ i' n1 T9 ?" p
复制代码
5 i5 B, J. f6 `1 i- _; a3 u9 W main.c文件
/ J; t9 ]+ {0 z5 u! \; j$ Z- /**
; |+ U9 n7 m! u" t9 y( T- v - ******************************************************************************
. G( A7 d0 P& d9 F# G# f P - * @file main.c
' h/ j1 B/ D9 B8 D/ h( f3 ]( m - * @author XinLi
( w2 O# X2 N8 v/ M- I# n - * @version v1.04 l5 E) L! Y0 S: |% t9 Q
- * @date 24-October-2017! ` N( o9 {* p( M
- * @brief Main program body.
3 E, K4 ~3 Q* `& _8 _ - ******************************************************************************' r v& C, j5 p: e
- * @attention
8 d' L+ Z1 Z/ D' E - *2 S+ E2 H2 {4 L# r! p8 W1 |' ]
- * <h2><center>Copyright © 2017 XinLi</center></h2>: v/ S# n( H, Q5 n0 ^0 l4 L
- */ U; w7 A* O, t9 U, Q5 P
- * This program is free software: you can redistribute it and/or modify$ l& M1 K' ]3 l0 C
- * it under the terms of the GNU General Public License as published by
* H* l8 D1 f) ~) F+ r - * the Free Software Foundation, either version 3 of the License, or3 C3 D9 d/ Q9 ?8 W2 d
- * (at your option) any later version.* L, u& ~- x# _% M. B
- *: u4 \. q5 i( Z* D) M, Q
- * This program is distributed in the hope that it will be useful,
( v) ^: k- q- z: x# N% g - * but WITHOUT ANY WARRANTY; without even the implied warranty of+ S# K8 v1 `0 [* H$ [# J, J$ v( s$ u
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the( u* m9 W' Q- K
- * GNU General Public License for more details.
4 C. E' ~7 \3 c x7 f1 f - *
" k$ K9 N, j6 r# j7 |9 a - * You should have received a copy of the GNU General Public License% b( h" ^' o1 O
- * along with this program. If not, see <http://www.gnu.org/licenses/>./ v( h! p, F3 E$ c; Q
- *
$ N( d, \$ t3 U - ******************************************************************************/ S( g% Z Z: q3 h! k* O
- */! R- x. N6 h4 H& s4 d" t1 L2 T5 h" P
- 7 O) s: g$ G- A5 t& \
- /* Header includes -----------------------------------------------------------*/8 x8 U: z% R! n7 }* |
- #include "main.h"
4 j1 f& S& o& M y5 { - #include "Delay.h"
+ Q, W& ~+ j ?; @5 Q- t" q! ? - #include "LED.h"
M2 o3 o2 _2 G9 k! |: \ - 7 L/ ^$ Q' K) n; c; z# x6 q
- /* Macro definitions ---------------------------------------------------------*/9 x6 m0 ]7 E: x9 w* Z! k
- /* Type definitions ----------------------------------------------------------*/
' f( H1 m# e" c6 v - /* Variable declarations -----------------------------------------------------*/ V! N- j2 l; o( x1 h c8 I
- /* Variable definitions ------------------------------------------------------*/: M4 a* M0 ] t
- /* Function declarations -----------------------------------------------------*/
1 X6 g) l3 ~9 ? u" M - /* Function definitions ------------------------------------------------------*/
8 v1 d* U- B4 l: v0 a# j p. i - $ r( R- u [+ s2 l2 o4 ]( D
- /**
5 _! V8 ^3 E8 F5 j - * @brief Main program.+ @' T) \) m6 I
- * @param None.
( k& B1 T: F" u: H* b - * @return None.
3 s. u% j- v2 a3 u: l D - */7 t! D F' ], L" T6 L& ?% ^4 X
- int main(void)
4 j0 x* U" S+ _; A2 e5 q2 L - {; q+ C# K$ D( o' o$ q+ F
- for(;;)3 K; ?( n" n$ F- ~; i$ W7 m! r
- {
- ^; x: u# N% h9 `* B" M - Delay_ms(500);8 {9 J/ q: ^$ ?$ n2 R3 `: V: U
- LED_SetStatus(LED_Pin1, LED_On);
0 d) M- h( C+ }* m - Delay_ms(500);
4 E6 l/ Z; x& B6 Z$ c - LED_SetStatus(LED_Pin2, LED_On);
: I* d* b( s2 _# X7 ?4 h- ?9 { - Delay_ms(500);& i* \1 D) B" p7 D L0 v5 N8 o
- LED_SetStatus(LED_Pin1, LED_Off);$ n+ N$ C" }; Z2 l
- Delay_ms(500);' U9 H$ f4 |, a1 y3 X6 c* D* e( J
- LED_SetStatus(LED_Pin2, LED_Off);
& E" M h @8 x% I- t- w - }
& n# F, M% I& T3 j- g& } - }
; r2 S& _2 K2 T n# E- _0 t
复制代码
: Z4 m8 H ?& E* N4 O3,注意9 Y6 @* E/ k( y" @
修改接口需要注意,LED的驱动方式和增减LED的个数。对应修改LED_Status枚举和源文件的变量定义。
" l" o$ [0 ^# E! W" ~, `1 U
/ A: b6 O( [6 z2 N' N) c1 |. I |