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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);* D0 l! X3 X# {8 N$ b3 s: r' C
  2.     HAL_Delay(1000);
复制代码

( D7 C$ Y5 _- K/ f9 P; |/ n& r

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


7 o# C# T; [$ H

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */8 J! n; _6 ^7 ?
  2.   HAL_TIM_Base_Start_IT(&htim2);  U7 M1 H( o6 A. |+ m% a( A+ B
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */
    * s1 O5 b5 X; l7 b+ P( L
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)0 `% J: S$ U/ v$ w% X3 p
  3. {* n9 S3 A6 o& o* {6 K- j8 O
  4.   if(htim->Instance==TIM2){
    ; m/ t8 v7 z0 R. l  n0 G
  5.     Timer3_count++;- Y6 j4 @- @9 M3 A& m
  6.     if(Timer3_count >= 3){
    % f+ Y0 @+ C6 m$ ?
  7.       Timer3_count = 0;
    # U: W" e/ Y3 k) [& J; d
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);   
    3 P! Y, w# ]( @4 c9 A
  9.     }
    * L) s: Q, Z/ Q8 p1 ]
  10.        " ?( w2 Y- x0 O: {- e& a) D
  11.   }2 A+ s3 D$ {* D7 _
  12.   else if(htim->Instance==TIM21){
    9 c6 o1 B- o$ H2 }3 i7 L* z6 T
  13.     ++Timer4_count; ' I& C/ A& P0 C6 s
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;   
    9 \, ^2 C0 P, j0 _8 X# Y
  15.   }
    $ k6 p( o/ M. H0 \9 \/ R' b
  16. }
    : ~8 z3 l  U1 v, M, N1 d$ W' y
  17. /* USER CODE END 1 */
复制代码

+ {8 p5 e8 ]0 |' }; I3、串口相关3.1 printf函数的实现& B, k: w& j8 y- Y' a4 e) q) K4 e
  1. /* USER CODE BEGIN 0 */
    9 \; D9 X, o6 C
  2. #if 1
    2 I7 x# e, l( b4 G  P1 c# o6 E
  3. #include <stdio.h>
    / S, U$ E( S% F$ z1 k- E

  4. " _; p& g9 V- S! n+ N
  5. /* 告知连接器不从C库链接使用半主机的函数 */( b6 \# X4 x3 J: g/ i
  6. #pragma import(__use_no_semihosting)
    / ~9 g! Z- P. T" x

  7. ! d+ m- J; K# g6 u$ L- S
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */( k1 F5 i* F, F% ?
  9. void _sys_exit(int x)5 |8 j) b' v9 S- f
  10. {
      ^+ h  j* k- v8 q" p/ B
  11.     x = x;
    7 h2 l1 l1 `  G" q5 D
  12. }, A! L  R2 G0 h0 x" s* W
  13. / ]1 f1 b: [3 N0 e
  14. /* 标准库需要的支持类型 */
    3 p2 u2 d; v, i- v
  15. struct __FILE
    / f7 O3 u: B" ]; H7 \
  16. {
    & m! \$ |# K; H) s# q
  17.     int handle;
    ( X- x7 s0 b7 ?* K
  18. };, H" V, y3 I/ d6 j1 u6 S4 ]

  19. 6 ]% y, R6 O' A8 {
  20. FILE __stdout;' X. x4 s+ v# s/ ?
  21. ! _3 q3 m4 y7 M3 x0 `% |4 t) J1 A
  22. int fputc(int ch, FILE *stream)3 T4 }- }1 v' L$ l" j1 H/ R
  23. {8 ^( Z# e1 ?7 t
  24.     /* 堵塞判断串口是否发送完成 */
    & n0 p2 j' {9 G/ H
  25.     while((USART1->ISR & 0X40) == 0);
    4 p2 S) {4 ~8 N0 m' m3 H
  26.   _# J' ]8 w1 k2 \
  27.     /* 串口发送完成,将该字符发送 */
    * ~: Y+ N, I9 B
  28.     USART1->TDR = (uint8_t) ch;
    " _6 p1 N2 L5 I/ A0 X

  29. . J5 F* E% x/ E& H1 j& T6 J; R7 f
  30.     return ch;6 P; }; h0 A0 X2 \; M* P5 G
  31. }
    9 ]; L, n9 q$ z! q
  32. #endif
    : Q* M. ?( o) X* f
  33. /* USER CODE END 0 */
    ! O! H# R0 W$ p' D8 ^7 s( p3 h
复制代码
9 F6 D) k: [+ X0 I5 U

3 ^4 h) w5 s, ?9 o% v7 Q0 v2 y

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


2 J  e; p/ t! Y4 J+ C, S

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

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

  1. /* USER CODE BEGIN 1 */& B+ I' \- g6 B2 L* @4 _7 J
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)+ j+ C; |. O# ~' u$ W8 o5 z( m# {" s
  3. {
    * \, i, Z4 S; k) Z4 M5 P- |
  4.   if(huart->Instance == LPUART1){# r" I1 J3 `3 o0 u- `0 M
  5.     Enocean_Data++;9 H, t+ g  q( w6 }" E$ ^" s
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);
    $ x5 P4 y5 r4 d3 K1 G" i6 @
  7.   }" P& M, s, H: o! w$ }
  8.   else if(huart->Instance==USART1)
    % ^: ^: t$ ]8 F9 j: X' a! z9 a
  9.   {
    9 ^5 u# Y+ S# `& T9 t( a
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); 5 m# E+ q/ Q& A$ ]; o6 R, o
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    5 ^! D  Z7 W* d8 c0 g) Y4 C
  12.   }
    1 v$ {3 @( P3 k" z/ k" G" n
  13. }" R8 R9 H4 x& a* d! D
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */
    - x: z- I; r+ A* g3 s; `: I
  2.   /* USER CODE BEGIN WHILE */
    ( j) D  S) i2 T% B5 t# u
  3.   while (1)/ a' G2 |6 [. o% f% L
  4.   {
    ; R: F/ S8 g/ e% a
  5.     if(test_data != Enocean_Data){
    . T( H1 q  I; a: I! A
  6.         HAL_Delay(7);
    ( w! i( h8 F3 R6 t- h; m, [
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    " d; h& u! d" m! L" M5 W5 Z
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区
    , D! ^) S7 Z5 w( O1 F" x$ m' T
  9.         Enocean_Data=0;" |2 x9 I( X) R0 Q
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错
    1 j/ [) E0 A6 ^) \( e0 {
  11.     }
    ( Q$ o! I: Q  v9 X; @
  12.     /* USER CODE END WHILE */, D7 @" r; V$ H# e9 F

  13. ) ~8 D/ i4 p! p6 ~- E
  14.     /* USER CODE BEGIN 3 */
    ' j+ G8 ~7 q. B2 S0 M+ I
  15.   }& q2 V. V4 q- ~1 |# c: @
  16.   /* USER CODE END 3 */
复制代码

6 [. z3 V4 M9 h3 `  g6 U

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

  1.   /* USER CODE BEGIN 2 */! ^. o1 h8 }1 O+ E" d5 {7 T, w
  2.   HAL_TIM_Base_Start_IT(&htim2);1 \0 U0 f! S0 F$ D% f
  3.   //使能串口中断接收3 Z; O* V; F2 t& ~9 X& P
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);
    2 Y0 S- `  M* }. d% v) f1 A9 [# A
  5.   /* USER CODE END 2 */
复制代码

6 N( l, v( @# J+ h$ ~+ b

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

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

+ E2 ]7 f5 I* k* s

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);
    ! q2 n# ~' F% ^, E
  2.   }
    / T% n1 f0 M3 v) s2 ?2 r& Y
  3.   /* USER CODE END 3 */
复制代码

# z8 j# _) O7 v/ L2 |

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


; {/ N' T0 ^" b

5、按键驱动移植

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

  1. /*
    " H/ P! F; u4 l/ ^5 c- n: ^& K
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下
    - N( m) }! A  C
  3. 和以前单片机项目按钮方式类似  
      x7 D( \5 d$ W: h) \/ ]
  4. by  qzh; e+ J& x; |5 e. [
  5. 2019/8/30  * h. {2 K! Q) A6 u! M1 W
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发  Z2 D6 m6 D) T/ }8 h
  7. by  qzh
    ; ]# G2 u" `% f" H$ _7 z: }+ f; ?
  8. */, c9 Z# Z5 s* T. x9 P7 ?( _
  9. #include "mod_button.h". G8 h. e1 e& A& L
  10. 7 b/ V- d6 g# @7 k4 [# T6 e

  11. ( }" F7 w, `5 G/ M- \# o  J& i
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
    # m2 w! o' s1 r
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)5 B, s; t% @4 q2 D2 {
  14. { , M$ E6 o8 d* u: d$ o
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);* r5 @! D9 @- c6 z" ~
  16. }
    : A- k1 j9 o( P$ ~, T. {9 C
  17. ! y' E# z, @" g- p) }& v
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  
    5 s  @5 N" Q! x+ u
  19. {
    $ s; S3 V. T$ m+ {
  20. // __HAL_TIM_SET_COUNTER3 q& T! m0 i. A
  21. HAL_TIM_Base_Start_IT(&htim21);
    + {$ I! x/ }. q1 a6 Z8 e4 Y* I
  22. // HAL_TIM_Base_Stop_IT2 Z2 \/ J- ]5 a) I
  23. // TIM_Cmd(TIM4, ENABLE);
    2 D  a" R# o* B
  24. if(pu8timer->on == 0)
    - c* R, j$ i$ T
  25.   pu8timer->on = 1;% ^9 M5 ?- D; V" z- V0 C
  26. if(pu8timer->on == 1)& \" e. A& N: {+ _5 a3 T
  27.   //IntNum = 0;
    7 z. i) d( U0 L) P
  28.   pu8timer->timeInit = Timer4_count;
    1 l- p2 A+ X/ E1 h+ v
  29. //pu8timer->timeInit = IntNum;
    + y, X& S5 J1 J6 @4 B
  30. pu8timer->timeOut = 0;
    % v* {  |( z- }' b3 U
  31. pu8timer->timeToCount = u32timeToCount;
    # K! o' O& E: l# q/ F2 Z' q0 d
  32. }/ t# O) o7 v& t7 |: U7 Q" w  t( i7 |

  33. % `1 M! Q9 @% n
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)! N0 o( A) N  L3 s  K
  35. {, q6 Y2 }8 J4 Z5 W9 ~
  36. uint32 Temp_Val;9 o5 Y) G, r- g, i; h
  37. if(Timer4_count > pu8timer->timeInit)
    ! F' N: @' `! h, j/ L
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;
      I! H  Q( b$ ^% B
  39. else
    $ K; ~) y6 b9 S- u( t
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;$ p# R9 @( H6 j( |
  41. if(Temp_Val >= pu8timer->timeToCount)
    # A0 U3 f2 b0 z' K( `
  42. {
    $ n$ Z& J0 N& `
  43.   pu8timer->timeOut = 1;
    1 _" M: A" V7 l' l; Y; R3 y) z: _) G
  44.   pu8timer->on = 0;
    : ^, a5 J, B, B. L* F5 A
  45.   pu8timer->timeToCount = 0;6 U9 }* }4 A1 y- |" F5 |
  46.   pu8timer->timeInit = 0;
    ( U5 [6 b1 e% v! ]5 H  l, F: l
  47. } " H% \" T* C, j- U" j
  48. else " s: N, p, y9 I( ?
  49.   pu8timer->timeOut = 0;
    5 l. j% x6 H! \4 |* F) }! F# P! O
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;
    0 G7 N6 n0 l+ J- K6 k2 P
  51. }
    9 |7 k, i) @' s& a& ]# l9 A
  52. 8 r% P) j$ O7 n, Q! Y9 ]/ T
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)4 s  x" H: r- J2 @  Y( X! S
  54. {
    4 G. i5 L3 h% K7 p) v8 |
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,
    - K0 x5 Q) P& _$ Y: {* U4 W- C9 {
  56.           5, 2, 5, 1,* |) a8 W. S: p1 {/ s; q
  57.           7, 2, 5, 3,
    0 p7 _+ V5 D& `( ~
  58.           5, 4, 5, 4,* ^; E' ~3 R3 k* D) M; W
  59.           5, 4, 5, 4,. b3 a7 ]. f% E8 k; f' \
  60.           6, 1, 0, 1,% c' K1 v$ l* K. l1 y: C
  61.           6, 1, 7, 1,2 x4 ?9 R3 r! [+ i) J
  62.           0, 1, 0, 1 };
    # t' {5 k3 z; q- [

  63. & f. ~& S' S) D' W6 Y. ~
  64. //register uint8 u8Input;
    / ~, s; W! P& |7 V' M& E
  65. uint8 u8Input;0 w# ?+ k3 h  {! h; d
  66. // Get button state
    ; ]* b7 R! {- d* w+ q: z3 v
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);# I# ^" z* z3 ^8 s0 u7 k8 S
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;
    7 L! `$ {4 y  x8 j" \% o" t( k
  69. " ^% Y: v% X6 M
  70. // Get timeout state
    / ]" g$ X# N' _& Y( I; Q
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);2 C% l2 L' r7 ~( E: s! k

  72. ( o: _% D. K4 ~1 s( S% o5 p1 d
  73. // Get new state
      Y& J( i6 y0 ^; ~
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action
    6 g7 W4 J/ u4 w; A( T8 ]
  75. 3 {6 b; L& ?+ \5 ~+ s
  76. // Perform action 2 c( E$ B% u4 m! ?
  77. switch (pBtn->u8State)
    9 i& Z, f5 j1 ]0 i5 M* j
  78. {
    " s1 f$ P' i; K) a; @
  79.   case 1:% G; \( P5 ?, F4 D0 J0 p
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);
    , Y% x# Q9 a4 x# T& L% u" }/ f
  81.    break;; N  g4 h3 |3 t, J
  82.   case 5:+ R+ w6 O% E0 R, I
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);/ W" M+ q  n, k* H6 P7 k* X
  84.    break;# s) q+ d$ z& c
  85. }
    # o- T6 i& u, D  G* C( i
  86. // return pBtn->u8State;. C8 O2 @& o' Q; N/ G# H
  87. //待测试
    2 Y! w0 a4 k- u2 H) V' Z
  88. return (BTN_STATE)pBtn->u8State; 1 D7 A( ]1 |' S8 I' B
  89. }
    - G% v3 {9 [  Y; L5 L" n
  90. 9 x& ~4 j. G: \, S& g

  91. & h( O) X& j3 [. S
  92. void Button_Action()/ i4 Q- E; ~( R
  93. {
    + l; g# K/ j$ j2 z6 L
  94. /*1 K2 m, C9 ]6 S. d
  95. 按键动作,模式选择
    , h) M# t, P# |1 I
  96. */
    ( U8 d4 l" D( K- I9 b7 u6 w
  97. }
      b& |1 Z  D, t- u  }
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED  M6 j. L/ p! z* w0 q1 j
  2. #define _MOD_BUTTON_H_INCLUDED
    + S: {# m4 S9 f! |9 g

  3. ! w; _6 v1 c0 [5 ~, C: c9 \
  4. #include "main.h") [+ B  }1 Y! q
  5. #include "Datadef.h"
    % e  [0 s0 i& e' @) S' d" i
  6. #include "tim.h"' E  k7 h4 j* G# s/ j: w
  7. /*
    , I# }, c/ n9 t
  8.        Timeout ON- {7 o( N  j- S" q( ^
  9.                 _______|_____
    1 _% ]. a8 t5 p1 r3 }: H& i# Q
  10. P             |             |    Timeout OFF+ E- E! {/ g$ a
  11. R  ___________|             |________|____/ k2 u  h! s- B# ?; C5 x
  12.   ^      ^  ^    ^  ^  ^   ^    ^8 l: Q7 J; l; V1 J/ m2 e
  13. S  0    1  2    3  4  5  6    7% T& |8 N  l! g: ]/ z

  14. % y/ c5 F: l9 P  c5 `+ J
  15. P - pressed, R - released, S - BTN_STATE( B& \* d7 @$ }, y' `
  16. */5 K0 y# O8 M) {7 h% o9 v) H

  17. ' n$ Z# Y7 E, Z+ U' p$ `
  18. /*  Y2 Z: D- Y- t, d) H
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6
    9 f) ~- M/ X0 p, B5 {1 G
  20. */! l, R1 t% S+ b  x% N/ V$ F
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND
    , I4 P) k' d. Y/ x
  22. : U; B, X0 a) l7 T* N

  23. - |3 g- e$ X2 I  `- I4 l9 q
  24. typedef struct- Z3 t4 P" Y# H" _; f  V
  25. {& }* ]$ ~2 }6 }$ @$ c  I
  26. // Public
    ! Z5 {) `- N6 A9 `7 ?
  27. //uint8  u8Pin;   // e.g. ADIO09 Q5 _  p- {4 y' E+ [
  28. //uint16  u8Pin;   // e.g. ADIO0
    $ J* P* [. @+ i! j0 l, D# o
  29. GPIO_TypeDef * u8Pin;" I, Q: H& G3 ~6 G
  30. uint16_t    GPIO_Pin;- _& s( p5 n9 |+ t6 J& ^# |
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState). M- o$ |* U* z! v- F
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed
    " p7 r9 V5 o+ S9 z
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released
    & A$ k# O( ^6 c7 Y

  34. ' C7 T2 Z; R0 v) ^; G
  35. // Private
    : A) A6 ?6 n: ~- ^
  36. TIMER_TYPE tTimer;
    $ g; f! s' q5 A" k% q) `
  37.   uint8  u8State;: v# l) f, W( t) O6 f
  38. - V/ a3 H) V5 z* ?- j, C! I
  39. } BTN_STRUCT;
    + O/ e- r0 l( }0 l" y5 b! |
  40. 9 R) p  Q; M5 e0 d1 @& \! v
  41. typedef enum
    # ]" E) z' v& |
  42. {& ]9 S  A& N' D
  43. BTN_IDLE = 0,5 m4 k6 E; N. b, t1 ?% @& s
  44. BTN_EDGE1,0 [4 w2 G5 r2 R: A& f2 o
  45. BTN_TRIGGERED,5 R, B' X) a* B( r$ x  p6 n' F2 Y
  46. BTN_PRESSED, //< most important
    8 l) y2 [' y4 @# m5 D% j
  47. BTN_PRESS_HOLD,8 Y4 }4 C  b, w( v0 A
  48. BTN_EDGE2,
      Q) F; K( H* L5 Y4 ~1 q6 }
  49. BTN_RELEASE_HOLD,
    0 i. f, I6 m1 m( e) \  ~% z3 q  {7 K+ u
  50. BTN_RELEASED
    5 M/ H7 `5 x$ A' j4 r8 i' o  l3 D; r
  51. } BTN_STATE;
    . a' D- T0 ~* Y& _

  52. ( C% t7 `# l4 y) k
  53. extern u16 Timer4_count;. e/ O% N* w) T5 t) _5 U1 y

  54. # Z, N5 q* P) G5 x6 Q5 ^
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);, A  R0 @/ P$ J; [- Q" i& B# H4 w1 H
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount); $ p( R9 i3 F: k, N) G6 I
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);8 \9 u5 Y! X4 Z1 u7 D% A
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);
    % c/ k# B, H; K6 ~
  59. ! J# C7 x8 V2 Q

  60. . j2 }/ W5 L  W; q# Y/ E6 m. u: w
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码

" \- l; e# p4 ^5 C

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

  1. /* USER CODE BEGIN 3 */
    ) \" ?  n; g- e* a2 N. v1 F
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){" t  j( c$ r% R) R' W
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);- ^( [" v% Y! A3 w8 ~% Q
  4.     }
    6 Q1 J9 ~. Z( [2 t2 T
  5. : K1 H+ q5 `* t! W) u2 x4 S. u
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){. z8 S, B! O$ f$ E
  7.        while(btn_getState(&K1_BUTTON_150mS));5 T' a! R  Q9 m5 ?1 W
  8.     }( |6 R) Y- E' B1 n9 A/ f1 f1 [) @

  9. 3 z/ t$ E, i5 a6 {$ P, Z' M6 V& |
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){
    : h6 y4 P5 |9 I9 |: E+ F
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);; ]7 R( ^9 K5 M( y
  12.         HAL_Delay(150);- N- o4 i+ @, h) _% @" s9 u: F
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ( @! W& I/ U2 v2 B9 E$ H& H6 [
  14.     }- T+ O5 ^- Z( T  P8 f
  15.     HAL_IWDG_Refresh(&hiwdg);
    , `( W! b: e# Z7 Z
  16.   }: {9 [$ @2 M# _4 X/ |
  17.   /* USER CODE END 3 */
复制代码

1 _! z  K# A! a

测试结果OK。

3 M# h& C- T1 Y; `7 Z

6、软件复位7 i, a1 P3 p3 D
  1. /* Private user code ---------------------------------------------------------*/
      K# R) Y% m4 `( k- c$ b8 G) `0 D
  2. /* USER CODE BEGIN 0 */
    % c, ]/ q/ m+ S, S9 `+ W
  3. void SoftReset(void)* Z) I9 c2 ^* D5 i* Q8 u) v" L1 O
  4. {* S8 ^! X3 k/ ^9 N$ m
  5.     __set_FAULTMASK(1); // 关闭所有中断3 c& v6 s; U. i" r1 t
  6.     NVIC_SystemReset(); // 复位
    5 Z* Q% ?5 C3 M' F! a# u' ]4 g5 U
  7. }% \; y* C1 M4 K1 G1 m
  8. /* USER CODE END 0 */
复制代码

7 ]3 J5 A! `1 `/ `& E. z$ Y  J
2 w4 t( b" w$ h! }3 q& m6 `

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

  1. /* USER CODE BEGIN 0 */! @1 F4 h& F+ O8 N" I9 l! g1 A
  2. void SoftReset(void)
    4 V( u* q) G) O& J/ H' H/ S0 ^
  3. {7 ~$ N( h4 [- m6 y. n; Z  n
  4.     HAL_NVIC_SystemReset(); // 复位" \6 Z( K! P2 \7 N' h. n2 x- T
  5. }( @) V4 b' A' w1 [  h" q+ ?( S) e0 G
  6. /* USER CODE END 0 */
复制代码

# Z8 U5 [- o0 h- A- O  A: C; g4 a

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

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

) v. Y: z/ j0 q$ b2 a

转载自: 矜辰所致

如有侵权请联系删除0 f0 S6 \# }) _6 ]

5 f6 \3 K# G3 [. Q' f+ v- @0 j6 b( `8 ^5 g5 z( L: s
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似技术帖

官网相关资源

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