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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);0 _- n6 g. c/ k: V% ~/ n7 [
  2.     HAL_Delay(1000);
复制代码

' X) N4 T" C5 ]' ]. o' O

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

5 X3 q' k. |1 w% s$ {

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */
    6 d3 o, a+ j% J' x2 k5 ^" f! B
  2.   HAL_TIM_Base_Start_IT(&htim2);
    . _2 l3 L1 a4 f/ w  b
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */  M( D2 K; `; [  F% C$ L% ]
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    # I2 l. J' R  Q
  3. {
    % W. d' U$ i. I! h( Z* p0 \
  4.   if(htim->Instance==TIM2){
    + e1 |, k$ ?1 g9 p
  5.     Timer3_count++;
    ; t6 @* a5 k7 C
  6.     if(Timer3_count >= 3){
    1 z9 Q; }- p- R4 U& M, I5 d% `
  7.       Timer3_count = 0;
    6 @; u6 S  y8 D! l) ^7 r
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);   
    / C+ d- K( t# P, d' L6 c
  9.     }
    4 L( P: J/ [! d# C3 @
  10.        & d/ K# Z& _6 P! i$ j/ e; F
  11.   }
    # e) M& X- _( x) D. C+ |$ x2 W
  12.   else if(htim->Instance==TIM21){' n' s% M7 c; {4 I
  13.     ++Timer4_count;
    * D4 ^! o" H0 S0 ?
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;    / E) K/ Z3 I% ?
  15.   }! h% F9 O" }& Z. ^- o: I) N
  16. }
    0 I( H' e7 K2 H# {: O! R: i
  17. /* USER CODE END 1 */
复制代码

( S/ g: B! b) `! a) B! p' P3、串口相关3.1 printf函数的实现
2 Q7 R+ c" N& o5 r- \
  1. /* USER CODE BEGIN 0 */
    ( b! C% F4 X( }* }) ]1 S
  2. #if 1
    , V0 g0 V! s4 T( e$ I1 z  R8 q
  3. #include <stdio.h>
    6 f' r0 @' ?% y$ D
  4. , w& r$ ?' h7 b  I# R3 R+ Q" g
  5. /* 告知连接器不从C库链接使用半主机的函数 */
      F& I: N. Q+ H% D3 y$ N8 o
  6. #pragma import(__use_no_semihosting)0 L! O% @1 M. s4 I& V

  7. # @6 G4 I# I; R7 S+ w5 P
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */
    6 Z! z( Z+ j- ~. G0 Y7 j
  9. void _sys_exit(int x)
    0 J, I# \. x) m* G; B, I/ u/ z' L
  10. {
    + c* c6 H: t3 b4 N+ Y
  11.     x = x;
    & S# [" x. T. \  C* }
  12. }
    , v7 _) I$ X1 L) U0 `% m0 s' @  y
  13. , M( P2 e& ?7 i% y/ x+ M0 o! Q5 _
  14. /* 标准库需要的支持类型 */) U1 h/ }8 v; }4 [
  15. struct __FILE
    4 Y1 X  {' T. w" [
  16. {9 Y5 s  H! m# q; Y! U
  17.     int handle;
    $ l5 z! b9 ^; g8 ~1 x# A
  18. };
    + u' w$ g4 `0 k8 P
  19. * z. o- q4 O2 U2 i0 u% X
  20. FILE __stdout;7 E9 A5 b) `- p3 U7 ~0 W

  21. 1 u! [- C) u) E4 y  s
  22. int fputc(int ch, FILE *stream)0 h3 O- t9 D" B2 N$ v( v
  23. {5 n& x7 N7 F6 D" E9 k
  24.     /* 堵塞判断串口是否发送完成 */  |8 @- {3 n( m; G" Z. t6 B. |
  25.     while((USART1->ISR & 0X40) == 0);
    % h8 b& r- ~  Q/ k, b
  26. ) L! g0 Q' b3 r6 n0 B1 r0 s
  27.     /* 串口发送完成,将该字符发送 */
    3 ~' Q# u, w; B
  28.     USART1->TDR = (uint8_t) ch;
    3 N3 N& z. G8 P8 ]

  29. + j  P1 J; h7 n
  30.     return ch;! S! P! I  L! n, b# ~
  31. }
    ; {: A3 A$ v* a( k# R4 c
  32. #endif
    : p( r* p7 U9 B& r1 \. L% }9 E
  33. /* USER CODE END 0 */2 H, y2 {+ x4 P- j
复制代码
. T4 J% U  f6 W- c

7 H8 O: O. A2 I3 O! _% d& T8 e

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

) ^! y1 b7 q: R: N: p- h3 V

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

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

  1. /* USER CODE BEGIN 1 */
    ) C" b, W' x( H! z' h5 m
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart). d5 \( `/ j7 Z
  3. {
    8 J! U* O* W/ V! f
  4.   if(huart->Instance == LPUART1){, ?- c+ w7 u; e6 X( g
  5.     Enocean_Data++;
    - f9 E' J' l0 T( H
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);8 {% Y* n: U; b) ~- F: n0 l* O
  7.   }+ F: E: U4 T' G( X3 [5 B: ^! P% T) U
  8.   else if(huart->Instance==USART1)- p" d& n8 A4 k$ P( P. e: K
  9.   {
    6 z  W% E$ R$ ~0 q' y3 G
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); , i- T. z% r9 E. E! ~; w
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    ( _' [: h+ E0 L& o1 H& V$ ~) V5 A
  12.   }
    1 `" r$ h, g4 [+ e2 m2 j! L
  13. }
    + ?' y7 l* d7 y7 ?& z  n# I
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */
      A5 k) b7 b4 t& U: H8 |( C; ^% y9 P
  2.   /* USER CODE BEGIN WHILE */  U* I+ M7 e; ~9 H2 y
  3.   while (1)# Q2 R) I% N' t2 F
  4.   {
    % V9 ^+ h8 E4 Y' C: Q9 E
  5.     if(test_data != Enocean_Data){" O& j8 Z0 q( q2 F" _( |8 y) f  `9 V
  6.         HAL_Delay(7);: R+ u$ R# d! S" X% x
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    6 g7 V! m' P' `: b: ~
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区
      r, D0 s; ?; ~5 C5 o  j' {/ D
  9.         Enocean_Data=0;6 _. v. P/ B# A9 b% r
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错
    ' J6 g( s+ a2 Y3 N) f
  11.     }! B- \, j/ H: M1 Q% ^3 e
  12.     /* USER CODE END WHILE */
    ) ~0 j( Q5 Q/ i+ A: N9 q

  13. / b9 T3 k8 T1 h, r. `. P
  14.     /* USER CODE BEGIN 3 */' O% I- b( \$ s' x
  15.   }
    5 ]8 Z) o6 \; [+ N: V$ b* m* C
  16.   /* USER CODE END 3 */
复制代码
$ ^0 J6 t% U# i

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

  1.   /* USER CODE BEGIN 2 */
    $ I9 ~7 X# v- J4 S
  2.   HAL_TIM_Base_Start_IT(&htim2);
    ' }" F0 `( p4 `. T
  3.   //使能串口中断接收
    - S" M0 [# c4 N
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);0 g- d' r9 M% w. C  Q" }9 r! X. }6 {* d: D
  5.   /* USER CODE END 2 */
复制代码
+ h; X( K0 D! j- ?# i  [# Z6 q

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

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


' K9 P! ^! l* O+ l

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);
    $ W0 f  O  ?5 S0 {9 I  t2 t. j/ T5 p
  2.   }
    ( k' z0 {. p2 e7 Y) V
  3.   /* USER CODE END 3 */
复制代码

8 Q& x  H2 ^9 S# t

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

" {/ l# I4 M7 C$ O' Z

5、按键驱动移植

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

  1. /*1 s5 y% g/ P" f8 F8 w6 ^* u0 S5 C
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下
    ( B( j$ }$ [$ o
  3. 和以前单片机项目按钮方式类似  
    * R5 l2 O, v5 G) D2 E$ l
  4. by  qzh
    + E0 @8 s3 A1 R5 P- R  I( x2 o, Z
  5. 2019/8/30  ' k+ U8 A6 S0 S2 y* [% z7 E7 t
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发. x4 P& K- [  [* N- Q0 D9 T
  7. by  qzh
    1 Z$ b8 u- I$ p0 e
  8. */: R: ?# i3 x0 }: p, X2 `1 D$ U
  9. #include "mod_button.h"4 b3 b% Q( l' D/ X) J1 h

  10. ) x1 v1 Z7 R1 T2 v" s+ G
  11. ( J! D4 l7 w2 [7 m8 ~$ E
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)+ s( k1 `) y" G% C) b
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)7 z- S1 o* C9 l; E
  14. { 3 O' b: I4 r; h* d) ]6 s
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);
    # ~, Y/ p9 o3 o4 y
  16. }
    . x1 _" a/ `+ q0 R
  17. 9 b7 N/ p0 E3 i. }6 ?
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  " U! {& J8 V0 w
  19. {
    % q, n  N5 o% b3 b1 u, B
  20. // __HAL_TIM_SET_COUNTER
    . x2 e& ~& S7 H1 c% o! V* ^
  21. HAL_TIM_Base_Start_IT(&htim21);
    6 B5 b7 o" x3 b, f
  22. // HAL_TIM_Base_Stop_IT
    : k; A8 J8 h1 ]7 f- D: T, h% ?
  23. // TIM_Cmd(TIM4, ENABLE);1 h" a" f% {2 b7 N& M+ a' e  _
  24. if(pu8timer->on == 0)
    : E9 E) U/ M# C8 ?* |& t; I
  25.   pu8timer->on = 1;6 C5 L9 ]; e! O" V$ {
  26. if(pu8timer->on == 1)( m1 X# p. R8 Y3 ]
  27.   //IntNum = 0;
    % A2 W$ I! a+ P: ^8 m
  28.   pu8timer->timeInit = Timer4_count;' ~1 A4 q. r4 V7 q: w
  29. //pu8timer->timeInit = IntNum;
    ; b& m( I( m: D% R  Z
  30. pu8timer->timeOut = 0;
    ' k0 L9 [% t! [
  31. pu8timer->timeToCount = u32timeToCount;1 ^. u2 O5 Q# v' S
  32. }8 [# E" S* \$ C, X3 p; ~
  33. % Q+ }# I! X" i. L. z1 L
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)2 `. B! {9 i) Q
  35. {7 _* F7 x+ t: K( g! X: m$ S' z7 q
  36. uint32 Temp_Val;
    0 @$ w; w0 L6 P$ y8 @
  37. if(Timer4_count > pu8timer->timeInit)
    $ e" j1 h% E: q. I8 _
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;
    " d6 W/ D4 ^: q1 z" Z$ X
  39. else( s$ m. `5 K5 s" I6 T! Y
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;
    ; C/ G2 z) o0 O& Y
  41. if(Temp_Val >= pu8timer->timeToCount)
    - P4 C! |5 f3 n% C. O) f! s2 U  z0 u
  42. {
    : u7 c; D2 r  d4 I; ?( Y
  43.   pu8timer->timeOut = 1;, i. Y! H' G% C; m0 A# i
  44.   pu8timer->on = 0;
    1 {9 i0 [; h" Q! S% X' }- J
  45.   pu8timer->timeToCount = 0;1 I0 l0 w+ F% ^) G2 I/ `0 K7 |3 D
  46.   pu8timer->timeInit = 0;
    6 I5 {$ F5 Z# q) v% T# S
  47. }
    ) A0 F( z6 Q! v1 n
  48. else # U, Q1 U, a2 b1 a& I
  49.   pu8timer->timeOut = 0;: U. x7 V* x' D+ }7 E* E
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;2 G* A; N+ j2 h% y& c
  51. }
    ; w5 D  H- ]. x8 |5 ?3 L" z

  52. # g& M$ Z3 ~4 X& p$ ]
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)
    ) Q4 `" B. G/ c5 R  V3 P
  54. {; u' [6 ~( x3 x/ Q( E* K
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,& N% k$ R  a4 o, y0 s1 P
  56.           5, 2, 5, 1,: v1 S5 @! T# c* t- f# z1 j8 w4 c# A* s
  57.           7, 2, 5, 3,
    ' `9 k+ v& P. z# R! S+ }
  58.           5, 4, 5, 4,
    $ M6 W% y7 W9 S* g1 o/ c" u& S
  59.           5, 4, 5, 4,6 w3 k# P! P' p& W! Y7 u" ~
  60.           6, 1, 0, 1,
    : ~" |4 W+ Y; w& J
  61.           6, 1, 7, 1,
    ! a& t/ a- n6 c- m9 a+ m
  62.           0, 1, 0, 1 };
    " O5 }- S0 B5 |  z; Y/ d. q
  63. / F2 X$ ~, M6 w: D5 y/ K" j
  64. //register uint8 u8Input;
    4 m9 F# ^# ^" ]  z2 F% H1 g
  65. uint8 u8Input;. S) K1 {% U: H1 y3 T
  66. // Get button state; V; Z) P0 a' m6 l8 I& S" t. I
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);
      T: |8 r, o- r( Y; c: p, F) Q( N
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;. ]. L9 W7 E# K7 }
  69. ' ~0 }) _. J* [: [$ Z& V* U9 n
  70. // Get timeout state
    , A- `4 o( b  y1 x/ h$ W; u
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);
    & }; F" Q4 m# ]
  72. 2 p8 u* f1 I  x
  73. // Get new state
    2 t& \! s4 Z; L
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action
    . f" m$ G* h; Z& T

  75. ! [, {  i  x0 p" V
  76. // Perform action 3 S9 f. I( t+ P6 Q
  77. switch (pBtn->u8State)0 J; S" B7 {- H3 r" {
  78. {5 f9 g/ h0 g0 P5 d
  79.   case 1:
      N: e, y1 J/ m% ^# x  }+ W) ?7 z' y
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);9 k; p9 ^; R% h4 q# U) L6 |
  81.    break;
    / q& k  b* p1 Z0 Q2 c. t" W) \
  82.   case 5:
    6 M4 F1 d6 b: K+ |5 I
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);( D3 k4 C2 X2 n0 V+ Q
  84.    break;
    2 K! z( R' C/ O% F3 `8 K6 ]3 U' L7 o
  85. }
    " ^$ p+ B: d6 I* M! h
  86. // return pBtn->u8State;
    ; G" _5 x! @. r9 b
  87. //待测试
    + ]: g/ o+ M' A/ N; a8 Y$ |  {
  88. return (BTN_STATE)pBtn->u8State; 3 B' R# Y, t+ o4 I1 R% J* d
  89. } 6 i9 m8 c/ \* A" B- X8 i: a
  90. ( x6 j& W$ ]5 s

  91. % @8 `3 P7 b2 x2 W* G( h* E. z
  92. void Button_Action()( O" U5 C" D/ O) K8 r
  93. {
    # d" ~1 f' ~4 b. S, ~, Q$ b
  94. /*
    ( Z" b/ I( H1 M; h; W1 N( a
  95. 按键动作,模式选择' q2 |6 `9 I/ C% v% a! L2 K
  96. */
    4 B3 R/ K1 b9 C3 c+ U. U2 C( x, G
  97. }; V! T6 [- \$ M7 D( W
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED
    4 ]- _" e5 m& A  D! g; Q
  2. #define _MOD_BUTTON_H_INCLUDED5 `# I/ |0 |% Y

  3. 2 D6 v. E. a' h) ]5 L4 |
  4. #include "main.h"8 j5 \8 s, H# H- O: |* P/ \
  5. #include "Datadef.h"4 g2 D' F% M- M3 b
  6. #include "tim.h"" f" {) a- U+ P8 A& E% N- l
  7. /*$ V* O7 ]! z- e% U
  8.        Timeout ON! O; P' y5 ?( @0 c
  9.                 _______|_____) A: p% m  F5 |
  10. P             |             |    Timeout OFF% u5 T( A) \3 Y" V( f2 i. W8 Y, |
  11. R  ___________|             |________|____
    ' H4 R; _& a. I! l( i" A7 ~
  12.   ^      ^  ^    ^  ^  ^   ^    ^8 `* d: b! J: U; }! Q
  13. S  0    1  2    3  4  5  6    7
    # X- Y; m9 I: A4 `3 ]

  14. * Y# M3 D4 G! _( o/ f, z# S, r1 u3 y& A
  15. P - pressed, R - released, S - BTN_STATE& p9 t# c; j6 \
  16. */) s+ E* R$ w3 q4 `

  17. 9 a; q! Q( G7 e0 ?" l* a1 m
  18. /*
    5 z8 ?9 I, v$ W
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6
    5 C2 ^2 f* \5 Q
  20. */
    7 Y+ d$ {9 z: z5 H7 K, s
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND
    9 T7 o% Y- |3 r/ e6 q5 `
  22. ! m4 d1 h+ Z3 Z5 k7 l: {* A+ @+ u; d

  23. : ~  u, V& Z+ @* c/ \
  24. typedef struct0 B' e* W: ^. ]0 F* a8 x
  25. {
    4 h2 D# n: d9 i& ^+ I2 s0 @2 s1 f! s
  26. // Public / d9 h: e/ n" e$ a$ Y: f
  27. //uint8  u8Pin;   // e.g. ADIO02 p9 v) n5 L8 ^. z8 z$ n8 _% D, Q
  28. //uint16  u8Pin;   // e.g. ADIO07 o/ f( a( s! ?' n) F: e3 K
  29. GPIO_TypeDef * u8Pin;; P$ ^: _" c6 H% k5 L; T+ n
  30. uint16_t    GPIO_Pin;4 ?6 O. o2 F3 K% V5 A2 V
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState)& |; \$ K4 [- [5 Q0 f0 g, i
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed
    . ^3 L8 n& k1 J+ f7 x
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released( f% j/ s! ~0 y8 ]" K

  34. / f3 e: y2 P- n5 J& z& t$ ]0 ?. p
  35. // Private5 \( G' ]$ E* E2 Z
  36. TIMER_TYPE tTimer;
    + h- }# N* y5 W
  37.   uint8  u8State;9 J1 T+ z0 `5 `. Z9 O" ]: h
  38. , v" Z" ^& G0 G# T. o$ M! W6 \+ I
  39. } BTN_STRUCT;9 m1 P$ s; _8 b

  40. ) t$ q: F7 i. ^* v1 w
  41. typedef enum
    - J( S+ n& ^/ \& O  O
  42. {9 }, k* z3 {4 L  {
  43. BTN_IDLE = 0,5 E0 s5 t2 h' D1 k! K; p2 \. K. \0 v
  44. BTN_EDGE1,0 v4 K$ A7 H/ \' f  v2 l
  45. BTN_TRIGGERED,
    ' `/ W' C! `8 K+ \' n1 r
  46. BTN_PRESSED, //< most important
    / P) a" E2 u5 h+ d2 I' `0 n
  47. BTN_PRESS_HOLD,9 j! y" K4 ~3 F/ E5 T
  48. BTN_EDGE2,
    9 Y# G$ A) N) Q1 p! p& u
  49. BTN_RELEASE_HOLD,8 E6 s+ u. u, O) l8 [! Z
  50. BTN_RELEASED % }8 S2 D- g! U4 f3 e
  51. } BTN_STATE;, N+ a& ^. ^# T: P% F

  52. # c, }5 [. N. Y5 o
  53. extern u16 Timer4_count;! g4 z2 M- Y0 d# f7 f0 ]  }

  54. ' i" C8 D3 i/ R0 _9 X4 F
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);
    0 T- g. f+ o4 n! R
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount); # A3 L# ?/ G! [% r
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);
    / Y7 R* s1 U5 d- \
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);' b" m  v" b% ~6 w2 Z* Q

  59. : F" Q/ R' _. I- K# V3 J( V) k' l
  60. ' ]/ S* S8 O& r2 P( Z" A2 U/ ~- D$ o
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码
- p% @! c3 v/ \" {8 h

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

  1. /* USER CODE BEGIN 3 */2 k$ X4 F+ {* t6 o; @0 U
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){
    ! G9 M) C5 O, w3 e. _
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);+ o* w, m9 e" l8 \' z5 w
  4.     }
    # A$ e; L' V& m! M. ~! r
  5. : [. M- P- X6 J  i
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){
    # R& f7 ~5 x$ u, @
  7.        while(btn_getState(&K1_BUTTON_150mS));" x2 L8 D3 f  z, t' {
  8.     }  s! R7 [# v  v  Y) d3 ~

  9. 8 F2 L- c7 l: S4 Y% w
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){
    & @8 `7 W" C/ ?0 B6 U! R! h
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ) n% i0 v& y  G7 U
  12.         HAL_Delay(150);1 s5 z  a6 f: F
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);' ]; B  Z8 Q8 l1 i
  14.     }0 j+ N4 v9 {- Y: H" M3 `# O. y" z
  15.     HAL_IWDG_Refresh(&hiwdg);
    . X8 p& s! j! [) S8 T
  16.   }
    6 ^9 \. o# M2 O* z
  17.   /* USER CODE END 3 */
复制代码
: ^3 r* o  L8 O  S$ r: \; L; |

测试结果OK。

% h4 y* X2 |/ b9 ]# a; j# }: p

6、软件复位5 Z" |( _4 s( P9 g' Q
  1. /* Private user code ---------------------------------------------------------*/. Z, |6 v0 u5 J/ s
  2. /* USER CODE BEGIN 0 */3 Y; G: K% _8 H( {* }
  3. void SoftReset(void)
    8 o0 S2 j! E/ {8 w6 j  E1 W
  4. {
    7 y5 e5 }5 |( W5 d
  5.     __set_FAULTMASK(1); // 关闭所有中断/ L1 U: d! |1 m0 c3 k$ f2 q: d$ f
  6.     NVIC_SystemReset(); // 复位9 K% T+ ]/ e) [$ z1 L
  7. }! i/ C$ m) y2 U% l, ^. u
  8. /* USER CODE END 0 */
复制代码
! m# Y% D7 E+ u+ I! i, A# ?8 O
4 }  _8 {' q/ |/ ?. m" z* U

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

  1. /* USER CODE BEGIN 0 */
    4 O9 V- X9 S$ E+ }) p
  2. void SoftReset(void)8 k9 }) t; h$ ]7 j8 \3 I7 H7 I
  3. {( ?0 `" c/ X1 O# J9 J
  4.     HAL_NVIC_SystemReset(); // 复位
    8 Y- U8 |- ?( L: F2 \* {% c8 `
  5. }
    1 K* N4 Q1 p* b
  6. /* USER CODE END 0 */
复制代码

* G9 r+ ?6 ]$ n* \

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

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

! c) T; h7 |% A# a$ [& }

转载自: 矜辰所致

如有侵权请联系删除# F+ s& L7 J* \7 [7 k" \+ {

( w1 v  t' o9 i% L! k
3 _% N. M& L( N$ B% W
赞 收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版