你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32L051开始添加需要的代码经验分享

[复制链接]
攻城狮Melo 发布时间:2023-6-12 19:18
1、LED灯的闪烁

在主函数while循环中直接使用延时控制:

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);0 ]. B0 u- y4 Y9 N# U9 K; D
  2.     HAL_Delay(1000);
复制代码
$ Y3 X6 L' h' g" f% b  q! m$ W

测试正常,这个延时1S钟靠肉眼识别,如果有误差其实也看不出来,影响delay应该是和系统时钟有关,后续再确定是否正常;

8 Y+ x$ m8 m6 @, f' T- P* W

2、定时器控制LED闪烁

在tim.c文件中对应处添加  HAL_TIM_PeriodElapsedCallback 函数,这是定时器中断的响应函数,当然,参数的定义(这里使用的参数只不过是以前使用F103保留下来直接复制过来的,我这里就没有进行对应的处理),相关.h文件的包含不要忘记添加。还有一个需要注意的,定时器初始化了,需要在主函数中开启定时器所以进行以下操作,LED会每隔3S切换一次

  1. /* USER CODE BEGIN 2 */& b9 Z& Q6 E. k2 n
  2.   HAL_TIM_Base_Start_IT(&htim2);
    0 `; H& L. W1 V5 X
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */% Z7 x" ^9 U8 l1 m# r9 Y
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    ) {2 m8 A- ?3 ^3 t! v  p
  3. {7 Z5 t( t% |8 b% Q/ y# W
  4.   if(htim->Instance==TIM2){0 l# Y& }% b! V) d  K3 @
  5.     Timer3_count++;
    7 Z% s4 J3 t2 n. v* Q& K2 }
  6.     if(Timer3_count >= 3){
    2 _: K, J3 B8 b4 I, w1 t
  7.       Timer3_count = 0;  E% b6 ]8 V3 j: p
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);    3 }3 d) M4 D1 d' e7 ~: `
  9.     }2 ]9 r! i0 q4 p
  10.        7 D7 I- l  e, h4 `7 u
  11.   }
    7 ~' q" U( w, d- o+ |" S) i
  12.   else if(htim->Instance==TIM21){
    7 U  O9 _1 G; p6 [4 _8 [
  13.     ++Timer4_count; ! J# V* J' D' f! Y, n
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;   
    6 b( J# q% c7 J1 [! {5 g# J+ J
  15.   }( {$ Y  @! N/ d' V8 h4 [8 }
  16. }; s! e, J/ f7 F2 r, M. |6 r
  17. /* USER CODE END 1 */
复制代码

% A% u( w4 j% C$ l% t- Y) G3、串口相关3.1 printf函数的实现
% q8 k/ Q1 s' t1 N: i
  1. /* USER CODE BEGIN 0 */" X/ ~* R1 V5 q* N; S! T1 s+ s# s
  2. #if 11 f) j3 Q4 B/ ~
  3. #include <stdio.h>
    ) f' p1 d" m% S! a9 K( a. c! K

  4. . a  w% i6 T6 j1 |- v( M- V2 p
  5. /* 告知连接器不从C库链接使用半主机的函数 */- ^6 t7 G1 l$ _4 k
  6. #pragma import(__use_no_semihosting)% A) D6 o5 t0 d; Z
  7. ; y5 V; x$ ]- i
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */
    ) T/ s; G( j; r* \" g" R7 Y
  9. void _sys_exit(int x)2 d& J+ t+ G9 K, f, u
  10. {8 d2 s4 A- p4 g  F8 A
  11.     x = x;8 H) X/ m8 w+ ^2 Z- Y' G
  12. }
    ; A! K# n6 c6 a' \9 q* @

  13. ! s4 w  A1 c4 j2 m! K2 k: j6 J5 Z
  14. /* 标准库需要的支持类型 */
    * b! M* t# d0 m8 P
  15. struct __FILE. b* V# ?& p: p* ]  Q0 l' `, h" W
  16. {
    & L# h7 \. X: L$ Q
  17.     int handle;- `( z! T9 O) I& Q3 p
  18. };& O& N9 n6 X3 @- c- M
  19. & \8 u! K" x* ~. m( o( T
  20. FILE __stdout;
    5 L% `; X' t6 f: [4 Y7 Z
  21. 8 ^0 p# L; ]& Z
  22. int fputc(int ch, FILE *stream). l: K" k+ T  t0 {  c$ _
  23. {
    ; ]  t- N9 f) f
  24.     /* 堵塞判断串口是否发送完成 */0 @( e, T! R" k2 u
  25.     while((USART1->ISR & 0X40) == 0);5 s, i$ Y5 e7 I

  26. 7 h4 M6 o+ b. |, G3 e5 v6 z
  27.     /* 串口发送完成,将该字符发送 */( n$ S% B1 z, X
  28.     USART1->TDR = (uint8_t) ch;
    ( o3 l3 k5 n9 [1 R1 _; @
  29. 8 R# O  p* J+ d* C" J: A' K" B
  30.     return ch;  h4 ~% O7 p$ W$ f: R  R# R
  31. }+ ^; M" o7 r$ @2 q5 i
  32. #endif
    ; V& p! s" q$ L' M" j+ [8 F+ R
  33. /* USER CODE END 0 */& f% H$ l. M, C% h
复制代码
" n: y& v+ e- y
+ M1 x/ W7 `# X" N! q- L

其中需要说明的是,如果是F103 ,不是 ISR 和 TDR 寄存器,而是 SR  DR寄存器

' _8 W! {3 v* c2 ?

3.2 串口接收不定长度的数据

在 usart.c 文件中添加  HAL_UART_RxCpltCallback  函数,对应的缓存数组不要忘记定义,我们这里使用的是 LPUART1 和 我的无线通讯模块通讯(以前F103对应的引脚是串口3),在中断响应函数中把串口接收到的数据存到 USART_Enocean_BUF 中,然后在主函数中实现打印接收到的一串数据。

  1. /* USER CODE BEGIN 1 */
    & ^( \% [6 {2 U6 l
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    " A# K- e5 Z; G/ O, m5 W/ Z) D
  3. {
    ( r. t( t+ O4 v4 m+ g
  4.   if(huart->Instance == LPUART1){
    " u( E  F" I! q4 G
  5.     Enocean_Data++;
    " p  h' U( f, ?& j! C
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);
    : K" R1 V" j8 v/ K" e  x
  7.   }0 i/ ]' y. P& ?* S7 K
  8.   else if(huart->Instance==USART1)
    0 D. M/ E* l) K7 _  J2 v9 N
  9.   {
    & |6 |& A  p4 d$ O. q- c9 f
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); * X2 h+ L3 z. s
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    , F  L6 l2 \* ]$ f7 M! W
  12.   }4 C; D, o; ^6 k- y
  13. }
    ; |  M. z% `! o$ H. C1 S
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */
    " G2 c2 z& M& ?. I% E, p  f9 R; }2 j
  2.   /* USER CODE BEGIN WHILE */( m: b+ Z' c. n, [5 {& B1 F
  3.   while (1)3 r4 d6 H7 v) Y. I$ w
  4.   {, H/ K$ o+ p! }( o( {4 k5 N4 ^4 x
  5.     if(test_data != Enocean_Data){
    ) ~+ i. k' \  D( f8 h
  6.         HAL_Delay(7);
    . x6 n6 K& l$ X0 T& [6 i5 Y
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   " n, l. W) I+ }- m3 U( n( Q) ~
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区
    9 a  [& x) e0 D+ y" r' V3 u
  9.         Enocean_Data=0;
    7 N" e) Q8 O: c* ?( k  W
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错# C" g/ n: \& V) s1 A7 H2 Z, G
  11.     }
    + _* X+ N2 P* @
  12.     /* USER CODE END WHILE */
    . f$ v) o" R7 ]4 w" k

  13. / n! ^4 o; {3 a, Q: Y. q/ n
  14.     /* USER CODE BEGIN 3 */9 j6 }$ w. L( x7 y) {
  15.   }
    * c- S" o  }9 O8 h
  16.   /* USER CODE END 3 */
复制代码
; y' D3 \7 J. m+ S9 e/ d

和定时器一样要注意,串口开启中断接收,需要在初始化后执行一次中断接收的函数 HAL_UART_Receive_IT ,类似于开启中断接收:

  1.   /* USER CODE BEGIN 2 */& e; l" Z& S! O
  2.   HAL_TIM_Base_Start_IT(&htim2);2 B+ U  ~% K% i
  3.   //使能串口中断接收1 z# _& J* q: ^1 P8 H* W) N
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);
    9 t; N3 t2 c) ~  N1 R( ^/ D
  5.   /* USER CODE END 2 */
复制代码

- l; K1 D" |: `* X

完成了以上操作,就能够实现将LPUART1 收到的数据,通过串口1打印出来

今天还发现一个细节,HAL_UART_RxCpltCallback 函数不需要再次在.h文件中申明,因为HAL库中虽然是 _weak 声明的,但是在底层stm32L0xx_hal_uart.h中已经申明了,所以在应用程序中申不申明都可以

+ W: ^8 R7 Q" Z+ T9 Z

4、独立看门狗

看门狗还是比较简单的,直接在循环中加一个喂狗函数就可以:

  1. HAL_IWDG_Refresh(&hiwdg);
    9 G# c; H# `, Q3 a% T
  2.   }8 P" U) N. e3 G$ k; ?2 N
  3.   /* USER CODE END 3 */
复制代码
( D0 c! X" y& ?, t

这里我也测试了下上一篇文章我设置的看门狗时间,当时计算出来看门狗时间为6.4S,是准确的。

6 Y6 @% Z1 a+ E9 i; A1 m

5、按键驱动移植

因为自己以前用到了一个非常好用的按钮设计,所以一直保留至今,直接上.c 和 .h文件

  1. /*- ]/ d; A; n% w
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下
    1 O, @5 [) m6 _
  3. 和以前单片机项目按钮方式类似  
    : U6 N$ S0 L' _  H% [7 I, F
  4. by  qzh
    & X, Q9 O! Y2 i
  5. 2019/8/30  - q% i$ j' G& J' w3 B% n) O
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发- Y5 W' N/ D. _! |# _
  7. by  qzh
    # R0 E4 A& h# Q3 Z, f% z! n" o# \
  8. */9 z1 i1 G5 ?$ v* ^3 e+ f
  9. #include "mod_button.h"
    : E, I5 n  ]% G
  10. 4 J. Q0 u. @  M8 j8 J* W7 R- V; u
  11. 8 s7 \. U9 d* X; X' S+ F6 c' ]" c
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)  s8 ^' b, h" W8 p3 o. _% ~7 ~3 q
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)
    9 e& o9 h5 G' Y7 e8 D, J3 o' A2 ]
  14. { 6 n! M+ H! m) L  P* ^) z0 O
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);
    + s; F$ P1 h* a1 Y7 k
  16. }
    1 O. I1 g9 ]3 ]6 T4 l6 S$ I

  17. 7 d1 S( O2 V4 J4 n6 _
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  / M2 T! l' ~: v! s$ j7 l0 x
  19. {. {5 a/ ?+ _+ m" i+ i
  20. // __HAL_TIM_SET_COUNTER
    : Z4 b1 m9 z! N' y* j2 l' p
  21. HAL_TIM_Base_Start_IT(&htim21);
    " N1 [; I! x4 W  R
  22. // HAL_TIM_Base_Stop_IT
    8 T1 Y6 r8 T& l) m% q* o3 I
  23. // TIM_Cmd(TIM4, ENABLE);4 h+ j" O4 I$ F3 d: X
  24. if(pu8timer->on == 0)
    ; p& X; X  t9 ^* |' r. z
  25.   pu8timer->on = 1;
    + j/ K( R: t. V3 u# x
  26. if(pu8timer->on == 1)+ K9 L: b1 F( ?( W
  27.   //IntNum = 0;+ ]2 [" I6 {' k& y( B+ b( _! l
  28.   pu8timer->timeInit = Timer4_count;; s+ G# B, n# a2 k3 {# z
  29. //pu8timer->timeInit = IntNum;0 [7 N8 |) y* j& a4 X& D' V
  30. pu8timer->timeOut = 0;
    0 I, X! L( @9 C0 \. m
  31. pu8timer->timeToCount = u32timeToCount;
    2 Q7 o9 N. h2 n) Z4 K
  32. }1 S. K0 r: [- |& Z  V

  33.   F# ^! f) d( s" m  S1 ]+ L/ N- L9 ?
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)' n1 b$ G" g, `
  35. {
    ; u4 Y- c$ B( x/ ^# f! i' J
  36. uint32 Temp_Val;/ G" |. [4 U* u9 d7 ^, z1 E% {
  37. if(Timer4_count > pu8timer->timeInit)4 C, R) N% a6 F6 L% |( |2 P' \5 G
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;0 e4 u# r* v  U% {- L# c$ _# U0 S
  39. else/ |1 Z5 t" L* `  r8 X2 W: x! ]
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;
    8 S, U/ J# h  W8 O$ Y
  41. if(Temp_Val >= pu8timer->timeToCount)
    8 N% A' H( ~4 s* U9 R  C# }
  42. {
    + a- v- `# X- Q, c. q
  43.   pu8timer->timeOut = 1;0 X. J" z1 R6 M' B9 ?2 x
  44.   pu8timer->on = 0;0 R& J; Q  M9 E; |2 X! ~1 i
  45.   pu8timer->timeToCount = 0;
    % i8 T6 ]' e4 \
  46.   pu8timer->timeInit = 0;8 |/ a$ {$ N7 U0 |) h0 ?
  47. }
    * i5 S, H( F2 N! E2 {
  48. else
    1 a/ [5 o. q2 H. @
  49.   pu8timer->timeOut = 0;8 W4 |' S8 {- J2 e5 C0 Q4 O
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;
    & \  n! D+ s0 q3 W! B
  51. }# c5 \+ t' I# j

  52. % c6 [) g5 n# y( f: r
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)  i+ P. @9 F# J0 h  R. Y* ?3 {: n
  54. {
    . i: n2 T5 W8 J! L! S( l" J
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,
    9 S8 u0 `; e- l& o  ?( G( w
  56.           5, 2, 5, 1,0 |& O# `$ p1 p
  57.           7, 2, 5, 3,
    $ P: e2 E% H6 `- V3 I9 S
  58.           5, 4, 5, 4,
    2 m2 c. W9 {4 `0 c' L
  59.           5, 4, 5, 4,
    4 @% N7 S' P/ K
  60.           6, 1, 0, 1,0 R1 [% G$ K9 c; L: D: R: K
  61.           6, 1, 7, 1,
    ; }% w: e! a6 T: K! O
  62.           0, 1, 0, 1 };+ E$ V5 c# ^3 W9 _
  63. 5 [: t  d# S1 M6 J8 ]  e0 F
  64. //register uint8 u8Input;
    * \- R3 p7 }# b4 Q5 X; {
  65. uint8 u8Input;
    ' [8 C: r" m5 U; j- Q
  66. // Get button state
    ; S( g7 ?3 Y" r- S: J0 H$ r' I: \' I
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);
    3 K* [3 I- J0 d' \% g; t( w6 F
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;* y  A* C( Z5 P4 k

  69. 1 [; M1 q5 g9 J- S- Y: w
  70. // Get timeout state
    * D5 C) e( ?1 o5 f. U
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);
    4 G; g# n& C5 R

  72. 5 H( o3 m' o0 g: d4 R  b
  73. // Get new state
    9 L( f8 D3 }$ O# _6 q
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action$ R8 P  c' ~8 {/ E/ `. h  \
  75. 1 f( E% e1 V4 Z2 L4 n
  76. // Perform action 2 x$ k. T2 ^; L+ s
  77. switch (pBtn->u8State)
    ( R: L$ C& V( u. T
  78. {
    7 O% c" U* {7 B
  79.   case 1:3 h3 m* o  k5 y* N
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);0 q* C" A" j! x7 s0 [- Z
  81.    break;" {. Y) H$ E: z
  82.   case 5:0 ^  H% k* E3 @
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);% K4 @4 S* c* y* p) p$ ~) o) ?
  84.    break;
    % E# }2 \5 T9 ~& u& p
  85. }9 ~5 z+ d9 x  K' i2 b  \6 P
  86. // return pBtn->u8State;
    0 O2 Q6 u3 H+ z1 B; i+ {
  87. //待测试% G- h5 A- X3 `; ~# [
  88. return (BTN_STATE)pBtn->u8State;
    6 r, d+ H( \$ n7 S2 }8 F4 i
  89. }
    , j9 A4 J4 x/ W
  90. " a. f' A! ]  J( }
  91. 4 {/ j' C# v3 b! |% ^# M. t
  92. void Button_Action()
    8 ~3 H# p7 k1 v% ~
  93. {$ G+ B" K' D* u  H4 P( y$ d
  94. /*- h: \% S: C# A- [2 A; w" @
  95. 按键动作,模式选择& I0 |3 ]8 t" }7 d4 J7 i
  96. */
    $ P/ s+ N- W4 u' o0 I' D! g- U) B
  97. }
    , Y" r: s. m0 K3 U& r: _
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED
    ( [8 {5 U2 |9 q
  2. #define _MOD_BUTTON_H_INCLUDED$ }3 S+ Z, J5 G/ F6 u# W$ N

  3. 7 C. _% K4 A' q
  4. #include "main.h") A& z4 p6 \, {. t8 l
  5. #include "Datadef.h"6 X4 j4 o9 y1 f5 {  s- b/ u% C
  6. #include "tim.h"
    8 g- c* h9 A6 V. {7 a! W
  7. /*% @& r8 m9 z- V, e* a
  8.        Timeout ON2 @5 c+ p  p+ [% ?% _( I
  9.                 _______|_____
    # L) ?$ U0 E1 e: h% P0 Q8 a9 k
  10. P             |             |    Timeout OFF
    ( S8 L# w) S; {
  11. R  ___________|             |________|____
    * n% o. t1 h5 m+ y" O
  12.   ^      ^  ^    ^  ^  ^   ^    ^4 W0 D* i/ j1 @: b; T, b6 q
  13. S  0    1  2    3  4  5  6    7
    9 n. D' V. I  B9 M: j4 r' S

  14. $ o9 t4 \0 q1 B; o
  15. P - pressed, R - released, S - BTN_STATE. p  X! j! Z0 b" I, T# ~2 K6 t
  16. */
    / t. {' n: N# X, j

  17. # [% o% S6 a9 P3 \+ T( x
  18. /*
    ! a3 m9 `! f& K1 d! A2 l: j
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6: `, Q. P9 z& e( ^
  20. */
    " g* @. f( K) z: n+ b
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND
    0 I& r- w* K: o6 T, V7 N

  22. $ I' h' L# A' R) `& q
  23. - x8 k3 D  v8 T/ d
  24. typedef struct
    $ l( q3 Z5 G* F9 d4 v
  25. {
    8 \: I. U4 T- k, v
  26. // Public
    7 z7 Q+ T+ w) ~* b0 x
  27. //uint8  u8Pin;   // e.g. ADIO0
    $ ~, G+ }! U  P
  28. //uint16  u8Pin;   // e.g. ADIO0
    0 f1 s( R, r/ A3 F; b3 k
  29. GPIO_TypeDef * u8Pin;' }( T9 s' t0 x+ X( o8 n
  30. uint16_t    GPIO_Pin;
    ( a; T% m/ ^! x
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState)
    5 f, K2 w& m( D4 w9 E( w# m* C* e
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed3 }/ k1 }" x+ `( D' K1 F9 S: Q
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released
    1 @5 l0 X" `9 T- D0 U1 J

  34. 9 ]* R) v, J) k' E- J& _
  35. // Private9 v7 K5 k, q2 R! T: J; E' D
  36. TIMER_TYPE tTimer;
    $ r: Q4 w) c+ S3 V. P3 B+ y
  37.   uint8  u8State;, x9 Y+ d1 c# @+ G  Z
  38. 3 F2 W9 S* n8 @, v4 H& B4 l2 `* S" I
  39. } BTN_STRUCT;# a% e6 m2 K% E- e& g3 n4 g
  40. 8 ~9 c. A9 Z9 f7 n2 \  T. T
  41. typedef enum $ G& q8 |; D; `8 h% E% U
  42. {
    9 A- X/ m/ C9 U
  43. BTN_IDLE = 0,3 d& _8 x' b' ]% P! m# A# J
  44. BTN_EDGE1,2 `- `1 X7 U; K" Q" r8 {
  45. BTN_TRIGGERED,
    # Z+ }6 N' h- i1 s
  46. BTN_PRESSED, //< most important
    . i* \, r$ a7 u# ]  g5 h
  47. BTN_PRESS_HOLD,
    : O1 x% y  V, k# t$ L- z
  48. BTN_EDGE2,: x7 {+ y, r) V" y- Y$ S7 a
  49. BTN_RELEASE_HOLD,
    : g: D- C" @8 d3 O) P% f( w0 s* t
  50. BTN_RELEASED & b/ b' G3 w6 m6 w4 h
  51. } BTN_STATE;* n& w3 k* T7 w* W' q. H
  52. & G+ Q# t6 I. D% y/ L1 _6 ^3 b! x
  53. extern u16 Timer4_count;3 \9 t8 W" c9 o: n4 a
  54. 8 W2 B2 d# Q# |1 C& r' Q! b1 ]
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);) M8 Q) K8 Q! R9 m9 _
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount);
    ( X/ j  L, ~( N) J# K% J
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);, S9 U" }$ q+ a2 e. T% |
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);5 G0 a0 s3 c# M
  59. / V) M7 M" R; h5 E+ ^! u

  60. 9 a8 r% _9 R7 x' N( L/ r" o: @! v! c
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码

$ k( F  K- W3 c5 o

在主函数中添加需要用到的按钮操作:

  1. /* USER CODE BEGIN 3 */, F9 f# c# w/ y) Y" }  K+ T
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){
    ! S+ j6 B4 X. B' ]3 H, R
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    1 W4 m) ]6 h; m( {0 A& T
  4.     }
      l" n0 c$ E1 Z# x) z
  5. , o; }- B# x& @6 I2 j% M. P
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){
    , k* V# Y% x, C* Q' Z" ]
  7.        while(btn_getState(&K1_BUTTON_150mS));
    7 M" W" `4 V# B& T. g6 c
  8.     }
    3 H& E0 }% t0 s* i) x2 P. u

  9. , ^+ x! O3 {; E& R2 h" O6 H+ h
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){& O! Q3 V8 f1 d
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ; S8 Z8 _+ b) ~, M
  12.         HAL_Delay(150);
    9 \0 v7 I, F' r0 C8 }
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);1 h  Q1 m3 ?) c
  14.     }# E: l4 q$ B: u& ?3 |% @
  15.     HAL_IWDG_Refresh(&hiwdg);3 h4 O% I1 b: w0 B8 @, G0 P' n$ s
  16.   }
      y, c2 p' D( ^; C0 g- b
  17.   /* USER CODE END 3 */
复制代码

! W4 J; B0 S+ g* R

测试结果OK。


$ o$ `7 `7 r' j: l

6、软件复位
; V9 T. x0 M" ?, o$ @% ?
  1. /* Private user code ---------------------------------------------------------*/  z$ ]$ w9 [% o# D' q
  2. /* USER CODE BEGIN 0 */
    ' C1 o0 u0 w& t) |0 @
  3. void SoftReset(void)
    7 G" ?/ B# R/ W2 V; D" s3 T" I' @
  4. {( s2 ]0 Y4 Y) q$ M7 T4 j
  5.     __set_FAULTMASK(1); // 关闭所有中断
    + c: F+ w- W  c. }) a2 O0 F8 k/ ?
  6.     NVIC_SystemReset(); // 复位! N9 s% b+ u. x: V4 I0 Q: |& A- Y
  7. }( h  O% K" L- }+ p( t( j  Y
  8. /* USER CODE END 0 */
复制代码

8 r! {: M$ z) Y2 X: X
+ d7 U% b  R! S5 _6 T

其实上面这个是有问题的,在HAL库中没有__set_FAULTMASK(1)这个,直接如下:

  1. /* USER CODE BEGIN 0 */( D9 d& |0 u; F  S8 `$ f
  2. void SoftReset(void)  S9 r4 `5 a( K: t
  3. {" P/ C- h  `0 \6 [& |: M
  4.     HAL_NVIC_SystemReset(); // 复位
    % _% F0 U3 M/ G4 C9 k
  5. }
    7 w0 ^$ M' I2 w9 Z7 T
  6. /* USER CODE END 0 */
复制代码
! N! s6 d) n1 }, L- Y- H9 D

或者直接用HAL_NVIC_SystemReset();这个函数在程序中就可以;

小结,基本上项目上使用到的串口,LED,按钮等功能都测试过了,然后我还得把通讯模块的底层一些驱动移植过来,其实也就是根据通讯模块的串口协议进行的一系列操作。这里就不说明,等今天完成这部分,下一篇文章会来写一下通过IO口,软件模拟的I2C接口测试。


0 O- Q9 C0 F: k& ]3 o, U5 h( q" \

转载自: 矜辰所致

如有侵权请联系删除# f( q3 {" E  Q/ U

; s" j: W( e& x0 k- \
- d9 x( n$ R4 T' x0 M
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版