|
STM32 点灯丨V2.1.0
7 m' m* u4 }$ Y# n今天把昨天的设想给实现了,目前来看,这个程序可以算是当前的一个完成版本了。 加了IO口的GPIO的宏,方面以后改IO口。 - #define LED_PIN GPIO_Pin_5 K4 n; |1 z1 C9 @, T2 \
- #define LED_GPIO_PORT GPIOB
$ M7 Q$ ~% t v7 Q e& \* V - #define LED_GPIO_CLK RCC_APB2Periph_GPIOB
3 Q* h. A4 n7 [. X# o - #define LED_POLAR 0 //LED的电平有效性,0:低电平有效,1:高电平有效# M& L- b/ m9 S
- #define LED_TYPE_NUM 3 //LED的类型数
复制代码 4 c$ u6 m8 y' ?
这样,以后就可以直接在文件顶部直接修改,而不用修改初始化函数里的东西了。 在参数里增加了,IO口的电平有效性设置(也用宏来管理了),如果下次改成高电平有效,我们只要改一个数就可以实现了。 - typedef struct
" v2 g- ?3 Y: { - {9 c k# G" E, @+ w
- u16 Err_num; //故障代码
8 C- ]3 d" u- Q0 T - u8 Type; //LED的类型,0:常亮,1:闪烁,2:故障提示
2 S6 Q$ H$ y- s5 _ - u8 Enable; //使能LED! e5 H, p) A( p- L+ g8 V3 D8 `" K
- u8 PolarLED; //LED电平有效极性
$ |( a- ?6 H: q7 I H - }LED_t;
复制代码
: R6 y$ h8 L; e0 H C增加了极性检测函数,这样可以更好理解和维护程序。 - /** @brief 端口极性检查
- y6 r- _$ M2 }) ~0 v- a, i8 S5 ] - * @param[in] polar : 极性
' L" R9 X4 o0 L3 E% d% G/ _6 L9 L2 \ - data : 数据* V+ a" U+ ]( H' m% l
- * @param[out] 无
# \4 Q) v3 Z: i: V( r - * @retval 0 : 无效
% {2 ]$ l v8 s; \, A8 U - 1 : 有效6 ^9 q! c* N) [& c
- * @note 无! V, d; Y! c- k( A
- */
- h4 k" \7 B3 f5 X) x0 o( I: p+ K - u8 sLed_Polar(u8 polar, u8 data)
, `* V# }: V/ o6 Q. W; m - {
* a! Y+ I, I7 X Z/ M; |3 N - if((polar ^ data) & 0X01) //极性相反" `7 j; h! e# {: J# r
- {
6 i$ x, ?$ r2 y% m6 l0 S6 A - return 0;
" c& u. r0 p5 ^$ _0 t' D; v& v/ H - }
- M& v( @& {6 m5 V - else' Z$ ~" G) F! w2 {9 \; [
- {6 U; T% Z) d' z& S, |0 L8 {; d
- return 1;
2 m' B; Q& ]. p+ P2 j! O - }1 }& H5 s6 p8 O+ K% z
- }
复制代码 相应的,循环函数也做了一些修改,主要是在输出到LED端口的时候,用极性检测函数,先检测一下极性,再输出。 - /** @brief LED循环' E# F0 h) B# s2 ]; e9 N- ]
- * @param[in] 无/ |6 C# } G5 o: H/ N6 Q
- * @param[out] 无( T' V7 Z$ G0 `" d$ U9 U! a9 Z9 }% _
- * @retval 类型
( I+ l+ u! @+ i - * @note 10ms# Z) @1 M0 O7 M/ a$ L0 a ]3 ^4 Y
- */1 o% K: ^1 _( Z: Y) S1 [6 [# P* K
- void sLED_Loop(void)
/ {2 a; r5 ^7 v$ r* u3 r& s - {
5 n) B. O0 Z- M8 b9 k1 K- F - static u32 s_Cnt;
3 }2 H( \& p+ h8 k6 o - static bool Flash;$ Q! Y# x" Z: {+ m; u) l
- static u32 ErrCnt;
# H( T% Q/ ?- [- m3 z+ a- r
4 h. W2 t. f; I7 B; ?0 z1 G- s_Cnt = (s_Cnt +1)%(FLASH_FREQ * 1000);8 e- i0 V7 Z# c: }9 i4 d
- switch(s_LED.Type)% p! m% l, x4 k
- {
- E; n3 Z$ |$ t4 |0 o: d - case 0 :4 x8 S ` W6 p- I" |2 c
- LED = sLed_Polar(s_LED.PolarLED , s_LED.Enable); //亮LED; J4 F3 m& j/ {/ A) t7 K" _
- break;
4 E3 W: C2 H ?5 h5 s - case 1:! T2 g" g" `* K3 d n
- if(s_Cnt % FLASH_FREQ == 0) //500ms,闪烁一次
# j1 H3 L, s6 W - {
/ h: A) H3 F8 o2 v - Flash = !Flash; //0灭,1:亮 $ C& [) a2 X8 `1 f" t
- LED = sLed_Polar(s_LED.PolarLED , s_LED.Enable & Flash);//检查极性
4 x4 t! |2 f3 e - }
% B6 r$ h: t0 m, _* | - break;! |8 U% z/ e1 B8 w" Y) v& h7 \! q
- case 2:
* e% Q R! k+ K, l - if(s_Cnt % FLASH_FREQ == 0) //间隔500ms- ?7 |( m2 U# J: Q. g
- {
$ u3 f' C- i* b: v( W! Q$ z - Flash = !Flash; //翻转
+ G* G- P2 O. B& }+ ~( ^% q - if(Flash == 1); }% i! ~9 v! D' U, m" h# \
- ErrCnt++;
# ~. F* J8 G' [ - if(ErrCnt > s_LED.Err_num)
% x/ @+ M6 c2 L( ?6 H h, ] - {7 A9 r3 \" E9 ?% V: ` I1 i
- ErrCnt++;
( @5 Y2 x5 B# R& ] - Flash = 0;# o5 J( L: l/ z2 l q& Q
- if(ErrCnt > s_LED.Err_num + 2)//灭两个周期
/ i8 P" A: G6 z& @- [1 P% C - ErrCnt = 0;7 r+ p% Y1 B7 u( D3 {" H" [
- }' g4 N. [' t5 Y) _3 Q; ?1 }
- LED = sLed_Polar(s_LED.PolarLED , s_LED.Enable & Flash);//检查极性
8 h0 [( p- H m/ g( t - }
, F# D2 [ ^% {& i - break;$ B0 @ E$ Y# i# x. ?' ]" ] M
- default:
+ _6 a5 J8 U T3 T* ? - break; 6 M1 p( p, |7 s! s; |
- }
1 Q' `. M D& M2 D9 C - }
复制代码 最后,就是昨天说的,设计接口函数,通过接口函数来设置、读取LED的参数。使程序更好理解,更好管理。 获取当前LED的类型 - /** @brief 获取当前LED的类型
v, y: a0 X9 [9 W8 h8 _' O - * @param[in] 无* h1 y/ c: h* f) _
- * @param[out] 无
! m' Q; i, }5 x: y% K4 C - * @retval 类型
2 _9 H% a" {9 a. N* S1 V# C - * @note 无0 g3 T0 u3 H( ]' @: C* [3 Q
- */
1 U1 `8 ?0 \/ d% p2 N& G - u8 sLED_ReadType(void)9 c3 L' @7 ~' c/ Q2 a5 H
- {. J1 Y3 X: b, a( [
- return s_LED.Type;$ Z: q; W+ v/ O6 \" m5 ~* N
- }
复制代码 设置LED的类型 - /** @brief 设置LDE的类型
: u1 ^3 j, H( G0 l! t) f/ F, n - * @param[in] type : 类型4 D8 D5 F+ Q3 m
- * @param[out] 无
# q; q+ o2 y. H2 d5 ~, b" \& j5 B, A7 E - * @retval 1 : 设置成功! T2 z7 c5 D9 U, W
- 0 : 设置失败" c* F, o: E' s1 v1 {
- * @note 无5 `2 F4 A( @4 E: i2 W: g+ s3 I
- */; b- \, }/ s I- w: h/ k; c4 y
- u8 sLED_SetType(u8 type)
# G. w g6 N) ~) |' |+ g - {
3 Y( c( `* ^) G2 X/ g7 H( H# n7 Q - if(type < LED_TYPE_NUM)9 u4 A5 M/ R( E
- {
- g) b9 l- B, v3 S - s_LED.Type = type;
( D' _3 Y& I- Z - return 1;
- ]/ N! l. k2 d0 T6 e - }
) l5 f; p4 B! S3 ? - else
" \' {- x6 O5 U. }! r - return 0;7 a/ W) o/ d' r# g( h& X: f
- }
复制代码
1 L8 r5 }' P! _1 O使能LED - /** @brief 使能LED
6 k; K. [# P6 E# J$ z- c" t - * @param[in] Enable :使能
+ x: h/ C5 s5 V; x6 [ - * @param[out] 无
/ |8 x# [7 M4 d, [5 f& M4 V - * @retval 无
' M! F g I: ~+ k/ N) W& w$ S* \ - * @note 无3 W1 r7 {( j, t6 @
- */4 R! ]7 u6 ?- M/ V9 G7 P3 `
- void sLED_Enable(u8 Enable)3 i: J8 e& Y [: `
- {
& T- A: l( V* i# H7 w - Enable = (Enable != 0);
% p$ S' f' K' \ P! _8 ? }/ A: V& M - s_LED.Enable = sLed_Polar(s_LED.PolarLED , Enable);
/ ]- p8 O! I. { - }
复制代码 * u! C9 n# s& C& D
这样,我们只要将LED的头文件包换过去,就可以通过接口操作LED相应的参数了,这样是不是就比之前规范很多了,嘻嘻。 按照惯例,放一个测试视频。效果还是跟原来一样的。 * y5 `% K: K/ A& p' L" ^$ X; _* N
如果大家想要工程文件的话,可以在公众号中找我要。 文章出处: Yue無缺 3 Y3 [/ h( [7 ]6 g# c
|