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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    $ y# g% ?. w4 E' E
  2.     HAL_Delay(1000);
复制代码

$ q* ]$ N: v# N8 u5 i

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


7 G' d, x& ?# n  l2 B" ]7 w) i

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */
    - T% l- a' C& N6 Y" R/ c) u
  2.   HAL_TIM_Base_Start_IT(&htim2);
    ) q' h. {1 z( F9 C+ b" t
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */
    : H' j2 m! P4 W3 r; z) N. N
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)& ]0 z" u: T9 D/ c
  3. {( X2 }) [6 z+ N6 O+ y8 {1 }" z, R
  4.   if(htim->Instance==TIM2){
    % U6 e; s7 }: W2 z3 H) B' O
  5.     Timer3_count++;
    . ?: l; i6 Q  }4 m7 `* A% V
  6.     if(Timer3_count >= 3){9 G$ Y  J: ]9 ]% {+ i7 K9 w  i
  7.       Timer3_count = 0;
    ! w- h; ]; [/ `7 q0 R
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);    % z% W" j. n1 o+ F) }7 D; A( v1 X) P
  9.     }3 ^) P9 h6 I8 g. b% D
  10.       
    2 J  H4 }. l7 w
  11.   }8 {: j! t# u) e
  12.   else if(htim->Instance==TIM21){
    ! e4 q7 C$ w! F: ^- G
  13.     ++Timer4_count;
    : M* U, a) |* F) u, v5 v8 i
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;    ) z9 |! `0 t) i8 [6 g8 k0 _
  15.   }3 C+ E% T' b* ~1 J
  16. }' h' G, E# m$ q: @! e) H* \
  17. /* USER CODE END 1 */
复制代码
6 f1 m* P# W( l! }
3、串口相关3.1 printf函数的实现( e3 G5 m$ j8 _! m7 o; R$ i
  1. /* USER CODE BEGIN 0 */
    % K) k! L) y( D0 ~1 ]: P! e
  2. #if 1
    ' c7 J4 v2 j! [# G
  3. #include <stdio.h>
    + W6 m0 }( `; M- x& T6 N3 n
  4. * g( Y# G+ T6 I3 x) Y
  5. /* 告知连接器不从C库链接使用半主机的函数 */, A7 @! \4 P0 X( w. b2 |, `
  6. #pragma import(__use_no_semihosting)
    3 L' S. Q5 ]+ {; y

  7. & E; p% ?) U: f& b- Q- S
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */
    , `' d; ?' K# O" i1 i+ x
  9. void _sys_exit(int x)2 J, r' u9 v, q0 ?0 I1 R5 n- A+ U. Z
  10. {
    5 z6 d4 Y9 z% |/ r8 n6 E+ ]
  11.     x = x;) g" {5 Z; _$ v! t& U
  12. }
    ; v" R4 z" `0 m( D' V

  13. 3 F3 M( D1 Y8 f, }3 C: K8 x5 X* p
  14. /* 标准库需要的支持类型 */
    ( v+ t" U& [! i1 ^3 p6 D
  15. struct __FILE
    1 L" G& Z8 o5 E: ^) Q# w2 u) j
  16. {
    , \+ v0 u' v$ C5 N
  17.     int handle;* X. A) d4 b/ U% F
  18. };
    ( w, y1 C+ t/ U0 k2 ?/ m  N: F8 J

  19. 9 b8 C" {5 W- J2 c! t
  20. FILE __stdout;) |1 @3 f- J6 m4 E' m8 M

  21.   M2 f. j3 x- f
  22. int fputc(int ch, FILE *stream)7 o( `! e8 q3 ?+ v( i# y7 [2 N
  23. {- M2 [! {  C; r
  24.     /* 堵塞判断串口是否发送完成 */
    2 L: @0 w- s; d, f9 l
  25.     while((USART1->ISR & 0X40) == 0);1 S5 ?0 P6 X+ o

  26. 1 J% i2 t/ Q6 H! Q3 n
  27.     /* 串口发送完成,将该字符发送 */1 y/ M7 _" ~% b! ^) s1 t  {
  28.     USART1->TDR = (uint8_t) ch;
    2 R! y) H7 J0 W# ^, {# E

  29. 3 F0 ~8 n' B0 ~$ Q$ V3 ?
  30.     return ch;
    / P: ^- L; u8 w3 r! \( l# {  K
  31. }9 N+ ]1 Y) h2 A( v' n0 T- {6 n
  32. #endif
    , R8 z2 R9 d& g4 V5 r- ]- e' N
  33. /* USER CODE END 0 */
    ; [( @) Z% P# f* `; U
复制代码

& s% C# F2 }3 Q+ ?" E. \1 }
& L8 }9 f( P( S

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


0 O/ W; g& B  o" Z9 |

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

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

  1. /* USER CODE BEGIN 1 */1 a* b7 i; ?5 ~, g
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    # \2 p9 F  S1 X( ^2 j
  3. {
    . c) Q& a! K: y7 ]% R7 {) w
  4.   if(huart->Instance == LPUART1){! I9 a6 f& m- V3 G- _& g9 T5 @! i
  5.     Enocean_Data++;
    / |& m$ Y3 x# e* R
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);& q$ w+ S4 S. C" A* i/ r4 U5 F
  7.   }
    3 s! F% F' \9 q0 W% s- \2 J& }$ F
  8.   else if(huart->Instance==USART1)
    ! e7 F7 ^! \2 u; i* u1 ^
  9.   {
    : S. Y8 a7 h8 E6 A2 x: [+ B
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); 1 a3 ~/ F6 F0 P/ R5 M2 r/ w
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    ' B, f0 N1 K/ {% D
  12.   }1 X( C0 g, \2 i( E, r. o
  13. }
    . p* u2 [8 f& M, l
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */4 l( @* }$ O1 q
  2.   /* USER CODE BEGIN WHILE */1 d7 q( L& g) M) V
  3.   while (1)
    & u0 k6 F4 q) j. \7 O
  4.   {/ e& B! c5 n- y% S, D% G- W" _  u  g
  5.     if(test_data != Enocean_Data){
    6 P- O, r8 b  b" a
  6.         HAL_Delay(7);  L; \2 w$ F9 O7 [; _
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    ! u8 D7 x( j2 z6 n$ c7 S
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区 " @' b3 r* c" d! a; A% h7 V; F
  9.         Enocean_Data=0;
    8 s' Y0 O* ~" X0 B
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错! w0 i. ^$ p' u) @$ _, j
  11.     }
    . z- h7 C; y9 `
  12.     /* USER CODE END WHILE */, {4 ]8 P; H' Y% o# r0 z4 w

  13. 5 q3 q; I1 k/ J$ \; t# }( X0 f
  14.     /* USER CODE BEGIN 3 */7 @! {# Z; P. {' _
  15.   }0 ?" `0 ?# D# E% }
  16.   /* USER CODE END 3 */
复制代码

6 x/ X- Z3 x; P

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

  1.   /* USER CODE BEGIN 2 */
    - L* U: ~0 A9 Z- z, k( ^
  2.   HAL_TIM_Base_Start_IT(&htim2);
    5 K4 z- Z, q8 t) `' ^# V0 W% b( z
  3.   //使能串口中断接收
    ! T+ D4 O; s, I2 C' J! j3 c' ]
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);
    $ h: u3 g( ]! q- ^
  5.   /* USER CODE END 2 */
复制代码
; r, v* [8 j' V, s7 x9 r

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

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

4 ?7 S- _0 F! r4 Y# ?) v

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);# {8 R# L9 _1 [2 e
  2.   }
    1 Q9 r. T: E% j  Q3 Q0 V& s
  3.   /* USER CODE END 3 */
复制代码
! c. M* q- h/ \) P% ?" U& }

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

& X/ z, }$ N7 o% d

5、按键驱动移植

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

  1. /*
    0 y& w* X  H; ^; Q, D
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下
    / _4 z. e. S7 N; e7 y
  3. 和以前单片机项目按钮方式类似  
    : N! n# G" q1 ^! v0 n" B8 @
  4. by  qzh
      c: z! }7 w- L5 b. n# R1 |0 u/ X
  5. 2019/8/30    P" [' k5 J% E3 [  ?4 W* q0 f& {
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发3 ~3 g2 X0 j$ j# p( e
  7. by  qzh, G! E9 V# [. f* A
  8. */+ A' Y9 y% E: n; C
  9. #include "mod_button.h"
    / V, ^# {% k* V* D8 O5 s+ Y, a5 d# z, Y

  10. # {0 F5 K2 W! l! m9 z( v7 J# H9 q

  11. 7 }& z/ _# @- e+ Z8 ?
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)6 T4 \6 O8 r& B* s+ i/ D6 c
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)4 l6 c. l9 I4 N6 J' M8 P
  14. {
    5 L  F0 H* T: {0 c
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);( i' C1 p. M6 n
  16. }9 r; E& Q8 A# O6 q

  17. " r% e* r1 N: i2 n3 Y
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  , g6 m- U. O/ G3 _; E) v
  19. {* R! G9 x9 h1 p: f- A" Z$ y* b
  20. // __HAL_TIM_SET_COUNTER
    ) }& }. |) R8 Z9 `: w+ l" s- ~
  21. HAL_TIM_Base_Start_IT(&htim21);
    & t% t/ V, F2 T2 r1 @% s) u( ?0 s
  22. // HAL_TIM_Base_Stop_IT
    # \6 Y; C3 S9 S+ r/ I
  23. // TIM_Cmd(TIM4, ENABLE);8 P3 E. A: p, ^1 P* o) _* e
  24. if(pu8timer->on == 0)8 h2 u2 H4 O. S' G
  25.   pu8timer->on = 1;: c$ G8 ?3 R9 ^# H$ ]' @
  26. if(pu8timer->on == 1)4 t# r$ o* e- Q' W, m
  27.   //IntNum = 0;
    . W' e+ [) ]$ M% s
  28.   pu8timer->timeInit = Timer4_count;$ D1 F2 p6 W8 X: P
  29. //pu8timer->timeInit = IntNum;" u1 O5 M5 Y8 _& s6 ^
  30. pu8timer->timeOut = 0;
    ( M) ?3 Q, ]  [  \! Z$ E3 `9 j9 T
  31. pu8timer->timeToCount = u32timeToCount;
    & `* `# v+ f6 ]3 T, O1 w2 b# _  @# T* z
  32. }' l; B+ m) n7 k

  33. & ~4 k' c& w0 u( i1 V  i5 i6 a
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)4 f3 A" l4 x7 J) @# k
  35. {
    4 F8 z7 x8 A+ o& T, U! O
  36. uint32 Temp_Val;: u; g4 I+ d/ i' e
  37. if(Timer4_count > pu8timer->timeInit)/ e4 ^$ g/ ~7 x2 |# V
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;
    2 V7 ?' ?& m' q  L# b
  39. else
    4 W4 H6 v1 v. h( ]+ H6 l
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;
    7 g; b9 E* G5 Q9 u* ^
  41. if(Temp_Val >= pu8timer->timeToCount)
    * Y; @. _% D: J9 v; V. j6 E8 M
  42. {& v- g: Z6 U( W8 `; X
  43.   pu8timer->timeOut = 1;
    . x6 A2 P2 _  @# u) m" T' A% X$ ~
  44.   pu8timer->on = 0;
    6 d7 h& u1 X; C7 e7 B% u8 G" ?
  45.   pu8timer->timeToCount = 0;# P- U0 V6 ]: ]6 w. V; e/ O. [
  46.   pu8timer->timeInit = 0;. H* E3 D# }$ M; x" e5 L  z  R& ]
  47. }
    5 l9 n+ z4 E4 V% c
  48. else
    ' y- O/ ]4 O# Z0 O( B$ ]3 z0 @  V
  49.   pu8timer->timeOut = 0;9 K+ |% x/ Y- E( `
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;. m6 q' D$ u/ o1 P, X7 C7 [
  51. }
    $ @& Z5 O3 T. I

  52. 5 N" R8 k! \5 `$ \! B3 N
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)5 v( K( a8 k, R: W$ A2 Y3 j6 H0 Q# f
  54. {+ S' o' @/ |% ^, A; P" X
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,3 u( m# J4 p; g( n* [
  56.           5, 2, 5, 1,1 @  J1 Z& u) l. u3 F  a
  57.           7, 2, 5, 3," H% r+ d0 K* C; N( @1 T
  58.           5, 4, 5, 4,
    % F, Y  z! u+ d0 {
  59.           5, 4, 5, 4,
    ; r: B) s8 _# A+ K+ \# g! p( D
  60.           6, 1, 0, 1,
    & s3 `, A; _. S/ Z
  61.           6, 1, 7, 1,5 Z0 Y* W0 j8 j* s/ U- t
  62.           0, 1, 0, 1 };
    # ]  v6 Z, B' P6 p$ p% `9 l, u
  63. 7 |* j7 E3 P+ P" f$ p0 k/ [
  64. //register uint8 u8Input;& d; F) A' _) X) ]1 W2 P# B8 {( b
  65. uint8 u8Input;- Y% t$ T. y+ W5 {
  66. // Get button state
    7 t. W1 F: W) ?0 a, Q0 \
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);
    1 O* l3 `) ]' g2 N
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;
    & L* c' |! A& }# K* a# J7 G
  69. - g) N. k. Y; n
  70. // Get timeout state
    * Q; J: t6 n' O# C2 X6 L& ^
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);0 d3 `. G& r, S2 _. r3 F! d# m4 B
  72. 7 N  U/ m" p/ ?+ g
  73. // Get new state! B; c% ~' ?6 T' c4 s0 c- S9 ?
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action9 [  g. N& w/ |5 B7 s- y/ O$ B1 w

  75. ( v9 S* k4 f, t: x  ?+ o' M
  76. // Perform action
    2 u, T# }# }+ D% `7 I- v
  77. switch (pBtn->u8State)/ f8 u/ b; Y1 a; ]1 L+ d/ H" e8 D
  78. {
    / M. m! n' X% b# Y4 u
  79.   case 1:
    ) |+ T2 R! V' J5 P1 E
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);7 e: D' ]' X$ ^. ^& {
  81.    break;
    # P3 f* q* P$ g3 }9 n  ]# e/ ~
  82.   case 5:
    6 u8 R% S# R% n/ U/ V
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);1 X6 k% R. O% s- P8 D
  84.    break;
    + T- M3 f- X) i* T8 U5 Y
  85. }) p1 `3 Y2 U/ q" L. a1 j$ P4 s
  86. // return pBtn->u8State;
    5 z. s- ?. E0 M0 M2 Q
  87. //待测试$ y# V; i+ C2 W% @4 J
  88. return (BTN_STATE)pBtn->u8State;
    - h& K& M. Q9 V2 x5 w& i# g
  89. } 0 r* m& R) d% A2 A9 U
  90. / J8 H! h- ?, s; L4 m+ ^& ^
  91. 5 |5 T: i' X( }1 Q- t4 k- S+ g2 N' V' d
  92. void Button_Action()7 @4 O" J5 l5 v
  93. {
    " i' `: y. X& A5 |
  94. /*& W& j9 x7 [4 C! \9 p# o, k0 H) g
  95. 按键动作,模式选择
    ) G' K# Y  N- ~' v& m- T
  96. */
    3 x0 t- x4 l* H
  97. }
    $ q; g* X/ |' b& B: L9 M
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED
    ) ?- w  d& ~+ t+ A& s0 O
  2. #define _MOD_BUTTON_H_INCLUDED5 ]9 U3 l% _/ O$ n

  3. 1 a  M  b3 ]; k6 O' P7 A* x/ F  Q. L
  4. #include "main.h"
    . u" E$ ~5 S$ r$ W' m/ L1 J
  5. #include "Datadef.h"6 J' m6 u/ e  Y: W. Z8 G
  6. #include "tim.h"% b2 O% T' r. u) g: b; B+ s( y
  7. /*& D$ A! E5 T7 F0 _4 P2 M# ?
  8.        Timeout ON
    " `( z" k4 Y* y: G
  9.                 _______|_____; K( L+ y, ?4 [6 U# r! K$ k; }* T
  10. P             |             |    Timeout OFF; I: s3 s5 y7 @
  11. R  ___________|             |________|____, V. k! E( _9 y
  12.   ^      ^  ^    ^  ^  ^   ^    ^
    . x) B9 e) K% r8 a
  13. S  0    1  2    3  4  5  6    7
    ' C1 K; r: `( o, C5 o* j
  14. 8 I7 Y9 e) J1 A5 x2 e+ ~
  15. P - pressed, R - released, S - BTN_STATE; P4 Z" z  r) V6 s' M
  16. */
    8 g6 Q; r8 ?: i7 F& L2 N( A+ `0 U
  17. + F; X5 y& d3 r9 X5 n0 y. B
  18. /*: M! A0 Y: k& m& q: w+ @
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6
    6 x6 y- S" [8 q4 z1 G
  20. */( u4 ]0 |0 K2 ~( ^/ b) P0 ^, v
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND
    5 V+ p" _  M# \' l; w$ |- K

  22. ; |( N, S% ~) o! z; S2 _8 B
  23. 1 s; P8 U4 a& q1 L
  24. typedef struct& \9 M6 _* ~) q6 D' X
  25. {) s$ ?) M$ k- O' r6 u; l
  26. // Public ; s$ T$ p% g4 V9 S3 g
  27. //uint8  u8Pin;   // e.g. ADIO0
    + s0 |$ F; A( @
  28. //uint16  u8Pin;   // e.g. ADIO0: I8 N+ h) e/ |+ X/ P7 ~
  29. GPIO_TypeDef * u8Pin;
    ) @* o+ I, F+ X- u% a# R# q
  30. uint16_t    GPIO_Pin;- g7 `+ Q$ {, w- i% U! `: F
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState)/ Q) f; M9 c% R0 `4 q" E
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed
    : N- G1 H3 o& {
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released: p* H+ R  G4 [# h: E. d/ p3 K  N
  34. - M% k" J, K* x% j7 W! z
  35. // Private
    8 ]9 g0 A. h5 l
  36. TIMER_TYPE tTimer;
    ; _- b: N; Z( T# D, g! j) ?/ b9 \6 ~
  37.   uint8  u8State;
    : c2 ~& P4 w: q% k1 C

  38. 9 S9 N: A) }! y: w
  39. } BTN_STRUCT;5 @% E* X2 k! A# t% L# q

  40. 5 a) D& N) V! t$ X
  41. typedef enum
    9 r: x* S/ U  s% z$ h
  42. {
    ' _% U' i0 K; h
  43. BTN_IDLE = 0,
    % J: J2 u! b( T2 y: Q0 V( m, M
  44. BTN_EDGE1,* X& K; P3 E6 z. l- \$ M
  45. BTN_TRIGGERED,
    1 B  W9 P" N  T& M6 C( ?
  46. BTN_PRESSED, //< most important
    # B8 w, X3 C/ C& {3 Y: l
  47. BTN_PRESS_HOLD,
    * p: Z- o7 x/ i0 i
  48. BTN_EDGE2,1 C1 a6 P# H' G" H& x4 A
  49. BTN_RELEASE_HOLD,
    ) D+ q: b: N. |0 A# Z& d1 V
  50. BTN_RELEASED
    6 k# p5 r# p' W! Q
  51. } BTN_STATE;
    ( h& e1 Q+ x6 g

  52. 4 n8 d) g( K( p1 W
  53. extern u16 Timer4_count;
    2 Q# v+ [  @3 `# ?

  54. 3 x* X% h$ @7 ^; J* n) y8 F7 V
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);) h( M! H( a( y, s
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount);
    & o4 K: `( [0 V$ v; }1 p
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);
    6 u9 O' X: ~! X# a/ p/ F  {
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);9 ~: s# h& s5 v7 m$ X
  59. ) l" M0 E0 ^5 B7 l' }
  60. * H; j, j/ \3 |* T3 W
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码
, t3 r% V. B3 j1 e$ P

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

  1. /* USER CODE BEGIN 3 */
    ! p) O! I1 @% I# K
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){6 t+ z7 m+ @9 u' c) ]
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);( _2 [& n* f9 `4 `+ @
  4.     }
    9 o3 a8 ^. Z( d+ {; X
  5. # d# T9 `* {0 v8 q3 t. x
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){" G0 L% c+ t7 e* O3 R
  7.        while(btn_getState(&K1_BUTTON_150mS));9 p$ l6 x- R2 R' q" Y. Z4 J
  8.     }
    2 h$ y, Y  e7 ^8 R

  9. , f  X5 X% n3 N& T( j
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){# k4 g8 E0 @1 l' |/ Y
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);  G5 B/ _: b* Y- V
  12.         HAL_Delay(150);7 b, U! d  l/ x. f# N" X0 z! ^
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);+ W2 W. s( v( M0 g' x" J
  14.     }
    6 @4 e" g8 P6 i4 H4 r
  15.     HAL_IWDG_Refresh(&hiwdg);5 x( ]: H; p* E' w
  16.   }0 F9 \# h! Q; t
  17.   /* USER CODE END 3 */
复制代码
. E8 v- v( Z1 M2 g$ l1 A. a

测试结果OK。

% k1 Y+ b$ _1 R8 B' C

6、软件复位
7 w. r, P  ?# {4 \" I
  1. /* Private user code ---------------------------------------------------------*/
    9 G( A6 K0 o5 S
  2. /* USER CODE BEGIN 0 *// ]! E& v6 b8 K2 o4 l! u) G
  3. void SoftReset(void)
    0 v4 A" n0 v( ^, \  }
  4. {
    . N8 {6 M6 H, N* }: K' \
  5.     __set_FAULTMASK(1); // 关闭所有中断: I3 I- F( R4 y7 {6 i
  6.     NVIC_SystemReset(); // 复位5 L& d. x: v1 W1 u. q# k" i; E
  7. }: O" d2 H4 ~( K# ]
  8. /* USER CODE END 0 */
复制代码

; t* f7 [+ E' l3 x1 F) t* e8 R$ R) n# F" T% v

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

  1. /* USER CODE BEGIN 0 */
    . {/ U$ l4 o2 ^& S$ `. u! p
  2. void SoftReset(void)
    # K4 K8 v# {, p+ N+ t+ a1 ]7 {
  3. {" u  V8 i/ L8 `3 c  J$ |: G+ R5 p
  4.     HAL_NVIC_SystemReset(); // 复位
    ) A- V' X: b! A4 g8 u) w+ n1 ~
  5. }
    & j- i; ]0 _2 S0 h
  6. /* USER CODE END 0 */
复制代码
) v1 g# t4 F" C$ K' T1 ?' X

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

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

! J/ \  S6 v1 Z0 R. k  e

转载自: 矜辰所致

如有侵权请联系删除: f9 B5 W: l" f9 Y" {* o. e4 y# M# y

' @6 a* q5 Y2 C& z! p2 u3 t$ ~  N( F  R1 g
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版