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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);  o) z. k! n$ E/ _7 f
  2.     HAL_Delay(1000);
复制代码

9 ^& D0 z1 U' b0 I; K% Y% R" j

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

- {% @; a+ v; i* h0 S# @  ~' H

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */
    / |. f8 n2 F: `+ p: I) S2 R
  2.   HAL_TIM_Base_Start_IT(&htim2);: m' Q- |; `- `" ]' t3 T. e
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */
    4 N, e! ^3 A; A) B6 ~
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    , }4 e, l$ A+ f
  3. {- l' Q* ?" H/ q! D. n
  4.   if(htim->Instance==TIM2){
    6 Y' e8 M8 ]* ^: C/ ~! m* L  y
  5.     Timer3_count++;. a) O9 z8 g% S# M4 N$ I0 D
  6.     if(Timer3_count >= 3){) h4 q! K' G$ @$ S/ Q* z4 r. G3 F
  7.       Timer3_count = 0;
    7 V# Q2 E5 \' L; w2 y' u
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);    + q7 o1 @0 J+ q! ?: ~
  9.     }# A' K* f3 Y% h/ Q3 n  _; i  z
  10.        $ W/ Z- s$ j; U6 e+ n. n
  11.   }
    3 ]6 k- I5 z; y( I  u
  12.   else if(htim->Instance==TIM21){
    / S6 E- r$ a6 c+ d2 k
  13.     ++Timer4_count;
    ; m; Q: f0 g9 g; d* z
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;   
    $ q% i. k* x8 S: J
  15.   }
    ' j( d3 j1 u) f+ O" t9 r7 [
  16. }
    ( k. B3 I$ W" Q# j# B0 p
  17. /* USER CODE END 1 */
复制代码
5 M5 x' f9 D/ u7 ]+ v% V9 d2 z
3、串口相关3.1 printf函数的实现- E: s& s/ G+ D1 F% E3 w5 p
  1. /* USER CODE BEGIN 0 */: f; s# O1 C/ f) `" J0 t/ [: I
  2. #if 1
    . p& x% M3 k7 a  u
  3. #include <stdio.h>* a2 c& v$ x) }+ C

  4. & w% G2 j& i' s& J
  5. /* 告知连接器不从C库链接使用半主机的函数 */+ w: `7 Y" h% H- b
  6. #pragma import(__use_no_semihosting)5 }& v, r$ Q, |' u- M( j, [9 ?, _

  7. 6 B, R5 e. z3 Z3 M, ]6 j
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */. M) w" Z) c$ ]5 [+ n9 }" }- O3 m. i
  9. void _sys_exit(int x)
    1 k+ R) l8 D7 ~5 y. w% |* ?8 r# B
  10. {
    + I/ z' g) ~0 J0 p6 B
  11.     x = x;5 q1 u8 |) H- S* j; A
  12. }
    9 J" f' ?) Y! B( V2 d7 s+ [
  13. ; i' q7 e0 X- f4 T
  14. /* 标准库需要的支持类型 */) I4 r: t1 n& ^  e: M
  15. struct __FILE
    : h" s& o, C* [
  16. {. V! I/ J* K- C2 [9 ?
  17.     int handle;
    ' [+ ^% O+ C! M+ F- v$ A) i
  18. };
    + i& D1 r' c% t0 y/ U6 K
  19. ; }4 Q; B6 \. M/ Q
  20. FILE __stdout;
    + N* _0 }) b! E+ ?7 C# m$ Q% v/ ?
  21. 5 M7 v9 ?' u, R, g  |  W
  22. int fputc(int ch, FILE *stream)
    # l, w/ W' y( y# ~
  23. {
    / o8 K7 b! p  l' k( d. K' s
  24.     /* 堵塞判断串口是否发送完成 */; E  x6 [: X3 Y% I+ B
  25.     while((USART1->ISR & 0X40) == 0);9 G0 g0 k- z9 F" @

  26. 5 `+ l/ U# J6 h. _' `/ Q4 W
  27.     /* 串口发送完成,将该字符发送 */; j- s; g2 t5 ]( P, y. p
  28.     USART1->TDR = (uint8_t) ch;
    # B$ l  D* _' u* D9 h' L) n

  29. 5 P$ e; I9 D7 ]/ E
  30.     return ch;
    . I7 R9 H" o* A
  31. }& C- _3 O  H" A9 Q- p
  32. #endif
    " i( a- @4 R! V! W; I' `
  33. /* USER CODE END 0 */) b" b) n* T4 k
复制代码
3 b. h2 }5 W+ b

: V- q5 [' r& y" D0 S

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


2 T$ k- O: m/ W( o

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

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

  1. /* USER CODE BEGIN 1 */
    # G$ p- |4 b1 b
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    0 F. l. e/ s5 e0 I7 V
  3. {* d. L6 r+ `: u4 F
  4.   if(huart->Instance == LPUART1){
    $ d! R! X) Y. P
  5.     Enocean_Data++;
    , Y$ v! D: c& O# b
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);
    # ~7 T6 F# ?2 d8 A; {
  7.   }
    / K1 L2 R" U0 c& L1 ?- j
  8.   else if(huart->Instance==USART1)
    2 c! V' ]9 U5 n6 Q
  9.   {1 W6 u/ _, `' s6 U  e
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); 6 E) j5 n5 r7 A  T3 g
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  ' Z) e/ r6 a0 p5 k" U( x, P8 `
  12.   }
    3 k1 W' O  V' `' e! ]; V2 ~/ C) z
  13. }
    , R6 ?4 i# o& Y3 X5 y3 o9 u
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */
    ' X5 o$ }; w4 w( y0 h6 I
  2.   /* USER CODE BEGIN WHILE */# z# @+ W: s! H! ?' O# I
  3.   while (1)
    " ]' W5 G, x: t
  4.   {1 _  h* }' {  h" J; g7 _9 O7 w
  5.     if(test_data != Enocean_Data){. z/ R' D, p! D5 j* }
  6.         HAL_Delay(7);% v! a- h7 Y+ m* J; _: E
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    5 B+ H7 \0 v3 P5 ?7 H
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区
    ; u  H/ y# m; q" W8 a: O- D7 P6 q
  9.         Enocean_Data=0;
    . V2 Y, y" L, O6 E* w0 l% U% p
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错
    ' C0 P" X- o' s, k) a9 Q) f
  11.     }
    . H0 E# j! W2 h3 [: \. }
  12.     /* USER CODE END WHILE */2 k% T" P5 I! r+ z1 U. J- Y
  13. & [+ G3 T. m" x( I9 J& r
  14.     /* USER CODE BEGIN 3 */# c9 K/ P- ]# [+ A0 x3 G; f8 D' [
  15.   }
    - K% c( [/ ~# c: ]/ x7 r* O
  16.   /* USER CODE END 3 */
复制代码

9 F0 v, z$ l2 K) @

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

  1.   /* USER CODE BEGIN 2 */
    ; R! R" K4 k! Q, }. c, R
  2.   HAL_TIM_Base_Start_IT(&htim2);
    . c  q7 C" C/ X. D4 S9 H; b: g
  3.   //使能串口中断接收8 N) ^5 W) O0 u/ |6 G
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);8 u1 z, q  S, u- }
  5.   /* USER CODE END 2 */
复制代码
1 c: _! }7 v+ Y3 ~

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

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


  x1 V: y! {, C" _$ X; y$ ~

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);
    $ Z* |% k- ~1 q4 r0 Q- p! V# c/ a0 S
  2.   }
    9 m7 W" f3 N7 Q' v# {9 P2 P
  3.   /* USER CODE END 3 */
复制代码

0 z" p8 O1 k7 `  o) R

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

8 R% @' _0 _% x5 a& n

5、按键驱动移植

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

  1. /*
    ( k# h' w) Z: M3 R1 C
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下2 }! L& a1 P9 v/ {9 Y2 r: |% W1 _5 U
  3. 和以前单片机项目按钮方式类似  
    8 k- @* g, Z( m/ ]+ h  L& J6 {6 I! W
  4. by  qzh  d0 i( \6 I8 y  C
  5. 2019/8/30  
    0 e! ]& }+ r; q3 ~' T7 C' i* \9 ]) s
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发2 ~% Z3 ?; {3 B$ e
  7. by  qzh+ n: i" x7 i% c) B/ E
  8. */
    * n4 B: ^5 ^6 U6 f$ v' G
  9. #include "mod_button.h"
    ; K; |, g2 W4 o& u. P: g5 ^$ v

  10. 8 i' C# ?  o" ]7 q+ }) o
  11. $ l' f6 L3 H+ V4 q9 s+ ?. g
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)2 M  f# d8 ?5 h5 c
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)* q% h, C  v  b; w. q- a$ ~
  14. {
    : a4 [3 X  v3 g  @( T* p# l! [
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);& {- M' D2 x8 ]3 |. K% f4 I' K
  16. }1 c. a) I9 f) u' a( m
  17.   @% v) \  J8 u
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  
    2 f# S) L) V2 @/ ]
  19. {
    # ?6 r3 g2 @4 f  W/ G/ d9 q4 K
  20. // __HAL_TIM_SET_COUNTER
    ' C$ H( V! @# ^  s( ]
  21. HAL_TIM_Base_Start_IT(&htim21);
    7 L& P5 W+ P, ]- M! I
  22. // HAL_TIM_Base_Stop_IT
    ' ^- B; e) T5 `9 v8 B0 @
  23. // TIM_Cmd(TIM4, ENABLE);
    # h; e" r9 w( _' E. v- M) X! J! h
  24. if(pu8timer->on == 0)* b1 A% v5 Z" p! h
  25.   pu8timer->on = 1;
    / M3 O- A7 K( l
  26. if(pu8timer->on == 1)
    + i3 _+ C$ j+ S* f) |% j3 \
  27.   //IntNum = 0;
    + R2 Q2 S8 c8 b" y# O9 @$ B) u
  28.   pu8timer->timeInit = Timer4_count;
    4 ]5 n- ?' I! r6 w# u3 K6 R- J: i
  29. //pu8timer->timeInit = IntNum;$ w& k# p) g5 Q0 ?9 P% ~
  30. pu8timer->timeOut = 0;! b  B6 s+ l! y/ x) ^( U/ t
  31. pu8timer->timeToCount = u32timeToCount;
    # T4 Y4 s" ^! m. s+ k/ L
  32. }
    8 A' G/ ]! Z5 y$ j7 o, l
  33. 6 r& o* {5 q/ h+ v4 w7 N9 b
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)
    6 n0 z9 y9 I# Z/ p' H% ?* P
  35. {; u. o' `$ J5 r8 G$ j- \
  36. uint32 Temp_Val;+ h& V! d' }) ~* K2 K7 K) B
  37. if(Timer4_count > pu8timer->timeInit)$ w$ l/ u0 m3 S6 j- n. c
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;# ^* D7 K* I3 H' l. {
  39. else' R9 u# O1 X/ a5 o; _
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;, p: F0 j* ~* u
  41. if(Temp_Val >= pu8timer->timeToCount)+ I  _! ~) j0 L6 B9 |9 u. _
  42. {( v; l! Z3 r" J5 s; F* V) Z
  43.   pu8timer->timeOut = 1;
    9 H' D: G, l  d# m3 r0 j
  44.   pu8timer->on = 0;- ?' D6 S3 F9 a/ U) M. @7 q, D9 V
  45.   pu8timer->timeToCount = 0;
    5 l* H* T3 @6 J. A1 G( c# U
  46.   pu8timer->timeInit = 0;
    : ~0 g. r+ Z6 T1 ~
  47. } " ]2 a! {- u6 T! r/ \
  48. else $ Z$ T8 q1 a' D1 E3 s9 D
  49.   pu8timer->timeOut = 0;
    8 l1 n' K9 ?2 j7 G
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;
    * @7 i9 [9 Q6 v2 s; z" Z' z) L
  51. }' P( `9 k5 E: t3 U+ w
  52. 7 T( E2 \0 G  L) u- C# w
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)8 @, _; s' O" h3 G# ]
  54. {9 w5 M% B8 j1 N  |4 S- Z
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,  H  q' p- }" J2 U
  56.           5, 2, 5, 1,2 v6 k3 O* H% {. {
  57.           7, 2, 5, 3,! t5 A! r4 m) f* c/ A6 l
  58.           5, 4, 5, 4,
    , J) ~; p0 l' ~7 u3 U: J0 y% w
  59.           5, 4, 5, 4,
    / x0 V' ^( s2 h& B' G/ u* j. w
  60.           6, 1, 0, 1,
    3 m# S3 i: P% W$ t! x) ]
  61.           6, 1, 7, 1,. s$ @7 H, s( d+ u$ t* E9 D( i/ \
  62.           0, 1, 0, 1 };
    3 n. X3 v0 m8 ?5 c
  63. 8 N5 y, d3 u4 d& t
  64. //register uint8 u8Input;% C5 b% z- T- O. }; A# c2 ^
  65. uint8 u8Input;
    5 j6 A1 x% h& `, c  E
  66. // Get button state
    ! Y$ v( R' }1 T4 c& g3 V" W
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);
    " ]2 |1 D$ @5 [
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;- e$ C1 Y! o1 h& U; `9 ]
  69. 4 I' b- r& ~/ c, L/ V6 J' `
  70. // Get timeout state( [8 E3 m  d% A; M) D, \
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);
    8 S: g5 W8 b5 m/ g. x0 W# O

  72. / y: t1 Z* h* q9 B8 W0 R
  73. // Get new state
      r" J% O( _/ z; x  U
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action
    2 O! }3 s1 v% E- t
  75. # s3 L/ t; J1 ?7 u* Z- E( s* c1 z
  76. // Perform action , L$ h: k- r2 `  j; B% I$ i
  77. switch (pBtn->u8State)
    ( I  L/ Q( B$ D; t+ e% b5 r% W
  78. {
    : R- Y5 m& y4 T# s" u2 F. \
  79.   case 1:
    : B& m) t1 V0 u4 Q* O( v
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);: K1 R4 p) b4 E4 B2 o& k
  81.    break;
    & m' k+ P; I" t3 h( T$ Z+ h
  82.   case 5:" W5 p; i! ]' A
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);9 N# k, Y# O/ R& S; O& o# p
  84.    break;# L) k! S% j$ k5 L
  85. }
    6 l; T1 q  S9 R0 ?/ r' {
  86. // return pBtn->u8State;
    , [4 M$ [2 \7 M' p* }& L
  87. //待测试
    # I5 S! ~5 D: O6 K$ t5 \  ^
  88. return (BTN_STATE)pBtn->u8State; 5 q8 J+ h4 J7 a/ M! E  M, i
  89. }
    1 S) q+ h* g3 N0 u$ m) W

  90. ! y5 B8 I# e% y0 Q) s# L1 b

  91. 5 [) {. H& c% b, b8 D
  92. void Button_Action()
    / j. z& ?  P( F2 F* C
  93. {
    , A; K% X$ ^1 P5 [0 y" j8 ?
  94. /*8 F$ \$ x2 |' b
  95. 按键动作,模式选择
    5 N3 [: P' Q& P4 d. X
  96. */* M2 Z7 A) K3 ?: ]. Z0 D
  97. }
    ! Z; t% o2 y5 c- l" `2 I
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED
    9 a0 G4 M7 S: u8 w: c: |7 _
  2. #define _MOD_BUTTON_H_INCLUDED6 k6 y3 e  k" p; H" Q3 F

  3. ! X+ ^6 d5 \9 d5 n1 o( t
  4. #include "main.h"
    4 [9 [. V# d. V& z8 Z5 h
  5. #include "Datadef.h"3 f8 `4 M/ o0 _3 i, {* K" q" }
  6. #include "tim.h"$ h2 v! g. e- j& d. a
  7. /*5 C& T' H' [& w' C( ~
  8.        Timeout ON- g* N( f! j1 J
  9.                 _______|_____0 e& z3 M/ Q3 T" v$ Y) I
  10. P             |             |    Timeout OFF
    7 z3 A) s- a' U% e0 |6 q
  11. R  ___________|             |________|____
    0 c" B% U8 x" y2 i
  12.   ^      ^  ^    ^  ^  ^   ^    ^. E. j0 Z+ E, ]
  13. S  0    1  2    3  4  5  6    7
    5 W9 M' K5 U$ _. D# \' t( U

  14. ) ]0 A1 F) G! ?: v( N+ @' h% R
  15. P - pressed, R - released, S - BTN_STATE
    ! [& A+ w& e3 L
  16. */0 y6 d" r) k# W$ a, `
  17. + G3 ]; l5 l( S4 j$ s  i
  18. /*
    % [6 V- a! m8 y- S3 M
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB62 p/ ^& ?2 h4 Q0 z
  20. */
    5 v7 [7 a) ?* G2 {+ w7 w
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND. V7 U! v! L1 n- W
  22. 8 G% ]0 [+ ]2 w" ^& Y7 T/ E
  23. 1 b: C9 K8 `+ u3 |3 o
  24. typedef struct
    ( ]6 P; R- B) v9 R' C9 C6 M. Z
  25. {
    : ^$ l% ?: Q% G( {' V1 g* Y
  26. // Public ' P6 Y9 ]: Y& P" b- k* D7 Z) J
  27. //uint8  u8Pin;   // e.g. ADIO0
    " ]! W; b5 Y* P. m. ^$ C% i2 d
  28. //uint16  u8Pin;   // e.g. ADIO08 U; I6 @  z8 l+ n. o
  29. GPIO_TypeDef * u8Pin;9 k/ B5 f% F7 B8 D# Y
  30. uint16_t    GPIO_Pin;
    5 H3 U; ~7 I! M# l& _) R
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState)& A" ]4 p: G" U% h$ }& X
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed
    6 E' r! F8 n- ~9 U
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released8 r$ G' N& d4 J  b
  34. + m% e% I0 I. p4 @1 O7 ~' m9 Z) H
  35. // Private
    5 Z5 E4 o7 V6 |
  36. TIMER_TYPE tTimer;! K! y, F9 E& ~! I% u
  37.   uint8  u8State;, S1 \: l3 t* ]

  38.   y: T4 }2 N* h5 \- O- ~
  39. } BTN_STRUCT;
    ( H0 ]5 Z! A& `0 |' j" ?
  40. . E; n# ]% l  f+ g2 P/ ?( \/ f* T
  41. typedef enum
    ' \* x* b+ X* e6 ]
  42. {6 e2 X  H$ T% O
  43. BTN_IDLE = 0,
    & H) [; n* s- ]! ^2 D% j8 m
  44. BTN_EDGE1,
    9 P2 [9 l8 m$ ~; @5 `# F
  45. BTN_TRIGGERED,+ ^' _1 ?2 ?8 x: L
  46. BTN_PRESSED, //< most important4 I4 P4 k4 p$ ?# z* H( @; \3 {
  47. BTN_PRESS_HOLD,
    % r/ l3 N2 M" S# S, l- v- @
  48. BTN_EDGE2,$ o8 |& X6 o0 n" w) q
  49. BTN_RELEASE_HOLD,
    , b) d7 [" L5 \! Z* x. D
  50. BTN_RELEASED
    ! D9 Y4 t& a( h$ [! E0 e' s
  51. } BTN_STATE;8 P( u1 {1 @7 t, C- u
  52. % O' C& n5 e5 J/ c- F5 G% ]
  53. extern u16 Timer4_count;9 @9 N5 i+ F* w9 W6 x

  54. . ~2 l, P: `8 @5 }# y+ `
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);. P# v! K9 I7 U" E  \
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount); % s9 f$ {) R  X* U
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);
      ?' w0 b  Q- G, c
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);0 i5 `! t. ~( d! {- Z
  59. 5 n6 J  L+ s& I4 _6 f
  60.   {; @* W  {/ ~8 x
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码

4 t, k, O8 `# H. B( G

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

  1. /* USER CODE BEGIN 3 */
    ( [1 _9 V) d# _/ T) K
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){6 Q" t" C: u5 I: C6 ~& j; Y5 S
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);4 x1 a. ?% N  L2 y$ Z: q
  4.     }8 q+ f; t" z6 I5 n4 X2 z
  5. $ e- T+ O' M" {! m/ K1 i
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){: }% U( E  o/ g* P2 ?3 _) e
  7.        while(btn_getState(&K1_BUTTON_150mS));8 B& y) M5 `+ t" @
  8.     }& u5 W$ c1 K  v! }9 ?: j
  9. 0 z& _4 L" ^0 ~6 g* z
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){6 n5 q3 c  @2 n/ ^
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    - R/ p, q* p3 _
  12.         HAL_Delay(150);+ y' X  W; D- o5 m4 h8 ^1 Q
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);( r8 _+ p7 R. b+ |9 g' k7 h
  14.     }( ?9 i! f1 H) x
  15.     HAL_IWDG_Refresh(&hiwdg);
    ) R5 ^& o" [& [! o$ R6 c4 _! O
  16.   }
    / `3 M8 K3 ~& b; V
  17.   /* USER CODE END 3 */
复制代码

7 B/ q$ Q! i: n5 X7 N: q

测试结果OK。

7 E. K; G4 P8 Z9 |: m% z1 z  E

6、软件复位
1 q# b8 e4 ]. q) y3 Q7 a
  1. /* Private user code ---------------------------------------------------------*/
    - B' L+ e, j5 n
  2. /* USER CODE BEGIN 0 */& b: w6 j( P/ G3 J) k+ A! r' k
  3. void SoftReset(void)/ Y7 Q( p& x+ j1 J) `* |
  4. {3 C5 H7 f5 j1 }* O
  5.     __set_FAULTMASK(1); // 关闭所有中断
      X- l  T' C% U) ~# Y, k- F5 B
  6.     NVIC_SystemReset(); // 复位
      {  S& Q. G8 o
  7. }( T% o! |" E' E' X6 u, ~, A& y4 f
  8. /* USER CODE END 0 */
复制代码

, ~! C3 x% t0 ]. j  w* K4 m4 L% O1 s

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

  1. /* USER CODE BEGIN 0 */9 e! R4 t. q. C1 Y
  2. void SoftReset(void), h- w9 [+ o, F) s0 m5 N9 I) x
  3. {
    3 Y5 v' B5 J. R" ?" t
  4.     HAL_NVIC_SystemReset(); // 复位
    , ]% b7 U9 S& ^7 t- s9 z
  5. }
    % M1 f0 ?, b0 n4 J( u
  6. /* USER CODE END 0 */
复制代码
$ V% ?9 F0 @. B4 \

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

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

- O3 A3 F; _0 X3 b6 t

转载自: 矜辰所致

如有侵权请联系删除. \( |& o* N# o3 Y% d

$ N% T% U: j8 _) g$ h9 Q" o% A: o, `- R# H$ R' G
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似分享

官网相关资源

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