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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    % ~0 L5 R; ~: {0 b/ g
  2.     HAL_Delay(1000);
复制代码
. \8 q/ g% S+ G, O

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

  o% o. [( l! M, w9 g

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */0 \) _( m$ {8 |5 V; f9 n
  2.   HAL_TIM_Base_Start_IT(&htim2);4 c; L6 R" T2 f) ?% o2 z3 z6 y
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */5 K4 f9 {$ u5 j! r0 @; ?- U3 {
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    / w; k/ \2 T7 h5 e+ f
  3. {
    & v9 A( K0 [# q" D
  4.   if(htim->Instance==TIM2){% o; X# h8 M0 G( Z3 `' j7 d+ s
  5.     Timer3_count++;
    ' r  _5 I2 q9 k1 I7 F- [1 `$ h
  6.     if(Timer3_count >= 3){1 F8 j* o9 V1 u: K7 w8 y4 A
  7.       Timer3_count = 0;# W+ T' t! W  x/ G! Y. {
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);    " Q) M+ A6 E4 j4 Q( A1 ?) L& B% A
  9.     }
    1 B. F8 S$ L* O, _
  10.        0 r/ ~$ {; G: N' s1 N4 R; R
  11.   }
    5 I& D$ t8 ~2 R5 P
  12.   else if(htim->Instance==TIM21){: f* @: X/ L2 U& o
  13.     ++Timer4_count;
    - Y+ K; x1 ?/ K/ K: Y4 Q" m0 ^
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;    ( k. ^- ^( }- _: U! W. h0 Z
  15.   }
    / \, ]2 V$ F8 Y" z: |8 z/ Q
  16. }
    9 z# C# }7 v4 D; m, |/ s
  17. /* USER CODE END 1 */
复制代码

' }' M) E/ m( J, }( P  D3 B3、串口相关3.1 printf函数的实现
4 b9 p9 a  i" v. ^! \; T( I
  1. /* USER CODE BEGIN 0 */4 x& g; z" {4 i" f& Q
  2. #if 1
    ! u: ~0 c5 T5 D: k; M, o3 f3 A1 Z5 M
  3. #include <stdio.h>
    8 O* n/ d6 V$ @0 q4 {; i; q

  4. ; l" y7 h% k* v6 T- U( R
  5. /* 告知连接器不从C库链接使用半主机的函数 */
    6 R+ x9 j9 A0 s( W/ G
  6. #pragma import(__use_no_semihosting)5 q% w" k9 A3 y7 X3 d

  7. " O! d9 z+ U/ I
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */
    0 H3 y' y3 Z; h
  9. void _sys_exit(int x)2 v1 v7 ~) L/ n* f8 B  F/ m+ n
  10. {
    - Z$ L4 A/ i8 b/ {9 P' O) S
  11.     x = x;5 H) {: l3 f! l
  12. }
    2 o+ s% i4 f7 V

  13. % C, h: W' h2 U# c3 c% M& l
  14. /* 标准库需要的支持类型 */
    / g) u- R6 e, r. w
  15. struct __FILE8 m5 ~, k0 _6 G9 C0 j4 \" s& `
  16. {" r" H2 n( N- b, `& ~7 o! ~* j4 A9 f6 ~
  17.     int handle;
    3 a/ H+ \! G  R/ F
  18. };3 Q2 W5 c' |- [- d8 W' `0 A
  19. ) w! [" _. w9 k6 f6 S' Y
  20. FILE __stdout;6 J% M+ y( y% s5 x; z) q5 j
  21. ' X4 e5 f$ P" x  y) X
  22. int fputc(int ch, FILE *stream)
    % g5 L% |1 O& M, Z
  23. {
    . z* I0 O# f' B' [( e3 w
  24.     /* 堵塞判断串口是否发送完成 */% P- y9 S' n5 F- O
  25.     while((USART1->ISR & 0X40) == 0);
    6 t" @* A$ G4 G8 C$ Y. a" [+ V
  26. 1 o7 ?6 d) h# R  j( N
  27.     /* 串口发送完成,将该字符发送 */
    + k) y& j5 `% ?
  28.     USART1->TDR = (uint8_t) ch;
    $ k/ \9 L  N; I; {, g
  29. % E. u4 ^! g( {+ B& V$ ]
  30.     return ch;! p# J- |* x' i. I9 Q- e
  31. }
    ) [( E4 R: l" Z4 h
  32. #endif2 `5 i& U; {5 ~* |" E2 I5 r0 |1 I
  33. /* USER CODE END 0 */
    3 d+ g+ k2 A, \7 [' v& ^7 u
复制代码

2 e9 e% I% `, |  q# J, x, x; I' [" ~6 C, W% ^

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

+ F4 R, M1 a' G) R, U0 H8 K1 M

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

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

  1. /* USER CODE BEGIN 1 */, B# @6 {1 ?  |4 x
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    / V2 Y# D" A" U
  3. {) o5 N5 s/ s5 b- b6 U% p. C/ O
  4.   if(huart->Instance == LPUART1){
    # e9 m" V3 O5 W' R3 r* L
  5.     Enocean_Data++;
    % G  b' p9 L, [$ w3 {* }& Y, E
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);) w5 K, z2 Q3 H" A3 U; z
  7.   }8 N4 `1 a7 w% P4 \. m9 g4 B5 g$ [: J
  8.   else if(huart->Instance==USART1)5 ^4 a  \% l; |/ ]4 X  B1 Z! _: m
  9.   {1 N# ?( d! n: H3 O3 s
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); $ I, x; K2 G' P+ j
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    ! [/ h) \4 `+ i* ~$ x/ E/ D- w5 L
  12.   }
    # l9 w0 K& l! Z1 W5 [* r
  13. }! c9 T! s( M7 E  [* u  l- w2 Z( E
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */
    $ H' r0 F5 G- y* g' C) G
  2.   /* USER CODE BEGIN WHILE */2 i6 j, k3 y+ k
  3.   while (1)
    * i9 @% t" m$ [1 J7 ?, Z( N
  4.   {9 E9 W+ G( P! E4 R6 n; a; n
  5.     if(test_data != Enocean_Data){
    7 {- I' q6 j. i/ s
  6.         HAL_Delay(7);& o) k7 L- W3 H
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    / C8 `+ m3 z' k
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区   ^: h) d7 q! z, r" ~
  9.         Enocean_Data=0;
    ! ]1 j+ t" x( R) ?- \2 ^# {" D8 G
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错6 C8 F2 [8 d, K8 L
  11.     }3 L; x. L2 k4 h, {- L
  12.     /* USER CODE END WHILE */
      h; z, m* j4 C, |. Q) X5 L' f

  13. - d0 H% r4 E- y' v. t* m# d0 J8 x
  14.     /* USER CODE BEGIN 3 */: f8 G/ i! c+ F4 a) c( X
  15.   }
    & h0 ~( s1 E' Y4 X
  16.   /* USER CODE END 3 */
复制代码
# p9 C/ R9 @$ W6 T$ _: f, G, O6 V

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

  1.   /* USER CODE BEGIN 2 */
    1 G, M! z  U' \- b" V. v9 ?
  2.   HAL_TIM_Base_Start_IT(&htim2);- h7 o* T3 V+ Y& B) ~5 g& N
  3.   //使能串口中断接收/ D' M. E& C0 e! [# C+ T) G6 D: [
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);- H" s/ [* t( B3 t! j
  5.   /* USER CODE END 2 */
复制代码

7 H& n1 ]4 \/ W

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

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


& G+ g: Y( ^! C: `. V% s+ e

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);5 X% Z0 c$ x  s7 |. i6 U$ @
  2.   }
    9 a! G( ?8 V/ a$ ?- c
  3.   /* USER CODE END 3 */
复制代码
. d- w6 v2 J. N; d7 r8 g$ G1 o! m' M1 a

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

  R8 M& {1 F6 ^" ^+ J( K6 t

5、按键驱动移植

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

  1. /*! d3 o0 ~" Y5 _) q0 @/ A
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下
      J! K2 @! x& S8 B2 N! Z
  3. 和以前单片机项目按钮方式类似  
    0 W2 z% G, r: b* M
  4. by  qzh6 I3 w8 u( f( O
  5. 2019/8/30  
    5 {& G( J# _" ]. e: [& b8 V8 r
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发! w+ r4 Z* p7 z7 s
  7. by  qzh7 z; m1 x/ f  @# [) ]( C9 X) j
  8. */
    3 Y; S0 X  D& ~5 b# w4 x% }  E
  9. #include "mod_button.h"
    * F8 B5 J! l" t* V' I5 }

  10. - i( v8 i% h+ u+ W: o
  11. * {% H& `& n" O
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)# S( y8 A1 f9 u! r, x; {
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)" d0 S" [& V; h8 Q. ]- B
  14. { - K0 i" q4 s" ?4 n5 g
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);
    " B. _* t7 H, R( L6 B2 A
  16. }. c6 Y9 ^1 i' J5 a0 p- O" i& l& X
  17. # b7 i! D! D" k4 a" V2 ^. d4 S
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  
    * P; j. Y: {" ?5 n' ?
  19. {
    6 n2 B% Z9 Z" X: y+ {) U
  20. // __HAL_TIM_SET_COUNTER' t) W! }$ k6 b. n
  21. HAL_TIM_Base_Start_IT(&htim21);6 I7 ~  x, J* Q; ^1 B. F
  22. // HAL_TIM_Base_Stop_IT  z: r. M. G, z( S7 C/ ]; {
  23. // TIM_Cmd(TIM4, ENABLE);$ W* ?! R3 P( H& I+ x' V  m
  24. if(pu8timer->on == 0)- d7 i* c) }% q" e+ Z& w3 C
  25.   pu8timer->on = 1;6 R! @6 Y% ~8 m% Y+ k. L' H
  26. if(pu8timer->on == 1)+ v' e8 @* e6 ?1 |7 q  Z
  27.   //IntNum = 0;: `( O6 {8 n/ |: x, G
  28.   pu8timer->timeInit = Timer4_count;
    7 u) x4 r3 v' t! j; W
  29. //pu8timer->timeInit = IntNum;) J8 b* d$ Q9 y2 S: k( V6 x3 C
  30. pu8timer->timeOut = 0;. l! D! h: d# R& y9 L
  31. pu8timer->timeToCount = u32timeToCount;. m9 w7 y6 R* p
  32. }: ~) M. r8 L7 L& a7 f* |

  33. 4 g7 e( e, _5 K7 C5 z
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)4 `  b3 o* |2 R6 k- r
  35. {
    * H: a, i1 T7 d! S
  36. uint32 Temp_Val;4 T0 u0 x9 M4 z
  37. if(Timer4_count > pu8timer->timeInit)
    . {' [, w. m8 n& _$ w
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;" ^2 `/ V# z$ s' g8 E
  39. else# Q: o( Q* s+ c2 n/ q  \- {
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;( _$ j& G. Q3 ]2 o
  41. if(Temp_Val >= pu8timer->timeToCount)& \  g  q$ ?4 X; I
  42. {" d( O4 T; l  K. C
  43.   pu8timer->timeOut = 1;
    ) X+ o( {  p' s5 k9 F- a: }! y
  44.   pu8timer->on = 0;
    + H" ~, X) P8 W$ Q
  45.   pu8timer->timeToCount = 0;( w, d! s! z( T4 p+ ?2 U
  46.   pu8timer->timeInit = 0;- }9 t* k9 |& M8 b! j
  47. } 4 I* `% ]/ S( m
  48. else ) h. h" f& ?& \, x7 i" N
  49.   pu8timer->timeOut = 0;/ K+ b# _3 I" P3 N! f0 \9 i. [
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;
    " U+ F: y7 s( k9 v+ K$ M/ v/ W
  51. }, k' o* |8 M% d" z% z. q

  52. 7 z; x, h9 L0 J- @8 v7 u
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)* g0 k8 J) ~* s- M
  54. {
    9 N% @1 v5 E! G0 C" C" I5 }
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,
    : i1 w, d" U+ _& |4 s& N- k1 m
  56.           5, 2, 5, 1," W/ `( d2 `$ ]! b  \
  57.           7, 2, 5, 3,
    4 Y% J4 Y" c: @
  58.           5, 4, 5, 4,
    7 i/ h0 e4 j4 W* p6 @0 M
  59.           5, 4, 5, 4,
    1 w$ @; m: A' I1 v, u
  60.           6, 1, 0, 1,/ g2 w' g4 \0 Y) k, v" g
  61.           6, 1, 7, 1,
    3 C$ P! t+ M$ }- R, |5 @$ v! O4 J% ]1 e7 }
  62.           0, 1, 0, 1 };
    $ ~3 c) }& m5 F2 s. P9 o  Z
  63. " Q1 r9 A. [7 M1 m* E* U6 l4 q
  64. //register uint8 u8Input;
    9 H0 {0 K0 M+ y: I- Q
  65. uint8 u8Input;7 O  X! v/ o0 x5 E2 w9 I, \
  66. // Get button state% A* H0 W: U- F
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);
    7 W- B. m# B2 K+ h6 T% C  Y5 s1 {$ E5 z6 ]
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;
    & z5 I; W3 k0 M' U$ L) J
  69. / w8 W6 m  U# `& ~2 o3 Y" y$ G; ^
  70. // Get timeout state2 [2 M: Y2 n- w7 C6 ~9 [
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);
    . l7 Q0 y3 h4 ]1 K

  72. 1 U! Z0 ?" @. ?4 p# a
  73. // Get new state9 }$ P( X& {0 r& V
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action* I, H, w2 q  A
  75. ( ~9 G; g& A. J2 n& s7 N
  76. // Perform action
    ( W0 r/ Z- Q$ N' e
  77. switch (pBtn->u8State)
    ' y3 J9 T: m% b% f
  78. {
    / y# ]1 D9 }+ ?3 l1 t5 I
  79.   case 1:: l% j  i; |, ]2 h" L# ?# l' a: }
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);3 E) U3 ~* f8 F9 H0 e3 d
  81.    break;  x4 o. L  X" Z! n) a. w
  82.   case 5:
    7 a8 m6 w% k2 n  a: p: \
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);
    2 I7 a) @1 B! ^5 ~7 J
  84.    break;5 ^* s* [* N" t" ]
  85. }
    ; ?1 A" G. x" i1 a5 W3 F
  86. // return pBtn->u8State;6 ~+ O$ c5 X* }# h& }& ]# V
  87. //待测试- |: L' v( H7 {! q6 H2 Y) A
  88. return (BTN_STATE)pBtn->u8State; 1 H6 C5 W& _- [0 S
  89. } : m( r- x6 k' j0 n5 J
  90. 2 H& K6 _/ G7 e: E8 V, ]

  91. , ]. a! E. k% i! l0 c7 _
  92. void Button_Action()
    * y# t/ _; N% x( }
  93. {! e- I. z. a2 B
  94. /*
    9 G7 _% j- g& ^' d% k# h
  95. 按键动作,模式选择
    ! Z& {% e4 x) A% R+ p& ~
  96. */9 B0 Z5 D. u- r/ p, _- d8 v& {5 j
  97. }9 E) _% f( P1 B  g" Q
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED2 s: K- m6 N0 w
  2. #define _MOD_BUTTON_H_INCLUDED
    3 a( D" E# }: s0 g/ s  A0 ~1 e
  3. + g% l+ G- P, G) |& B$ B: e
  4. #include "main.h"
    " i/ G6 ~. u+ a6 q9 Z1 c  t
  5. #include "Datadef.h"
    - C+ Z$ f" l6 e( q( i7 q/ `% t
  6. #include "tim.h"
    ; y; k6 U4 f/ g, J! }3 K: O
  7. /*
    4 Y; a/ Z) K0 l8 Y2 m
  8.        Timeout ON7 m8 E/ i- b0 Z+ i
  9.                 _______|_____: \, c0 s" x+ E( v
  10. P             |             |    Timeout OFF7 X4 z9 W1 v6 G3 G3 n8 e
  11. R  ___________|             |________|____, u0 q2 E5 C# b( v& _: q
  12.   ^      ^  ^    ^  ^  ^   ^    ^% @1 U5 A, O: g$ }) D
  13. S  0    1  2    3  4  5  6    7
    8 ?! E0 s/ m  l0 I9 R' j8 ^

  14. 7 i! Y4 Z; b; X9 [; J
  15. P - pressed, R - released, S - BTN_STATE
    ) g. z+ H4 g$ ^  }7 ?7 N# A# k7 p
  16. */
    # a& |2 [( g6 }" V- p& f# [& X7 H
  17. ( a: c/ S- r. V3 |  |0 w
  18. /*
    3 u6 {0 Q' @+ x* u4 Z9 v
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6
    ) u6 _/ I# F2 Y8 a) Q! d
  20. */
    & Y& y1 ?4 \, ^$ ?
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND
    * v" k; B' q5 a" R3 V9 X- u

  22. ) F( y- g+ [2 x" }) d8 l

  23. ' y- A# s- q! x' [9 V0 b) m' A3 ^
  24. typedef struct
    $ d, Q& h: Q: e
  25. {
    - O# ^% ^- U( W8 j
  26. // Public " \7 P7 i# M6 D& K
  27. //uint8  u8Pin;   // e.g. ADIO0* C4 F9 \& {* t% E: B! Y5 t
  28. //uint16  u8Pin;   // e.g. ADIO0' a5 c$ y- O4 L" [7 }& C4 i
  29. GPIO_TypeDef * u8Pin;
    0 G+ w& O& c7 A! \# w4 q
  30. uint16_t    GPIO_Pin;0 T$ }6 z8 }4 E7 r2 O
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState), S1 F  f1 I+ a% x5 v
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed5 U9 J& L: B" t4 z  t
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released
    ) D% @' p* ?$ v1 L2 O
  34. , W% X- g. U* c  N1 u
  35. // Private$ A6 |% N6 s4 ]8 D2 z+ _
  36. TIMER_TYPE tTimer;6 b' [3 o% l1 ]" j8 ?  J* A# M5 Q0 u- K
  37.   uint8  u8State;( Z0 \! o4 i/ G6 O& O+ d4 X" v
  38. # }. k' L. J, p* h
  39. } BTN_STRUCT;% A- v( z+ L$ |: Y
  40. 0 t' ~4 y2 m  a4 f* G' c% z
  41. typedef enum
    7 o& f% G0 G2 v  O6 n, ?1 a4 w
  42. {7 J0 d$ m  j: R( F9 `+ m
  43. BTN_IDLE = 0,
    : g+ A$ I. X) o% D: u
  44. BTN_EDGE1,' g9 p. i* m5 X3 p
  45. BTN_TRIGGERED,
    7 E3 ?) v6 @; u7 F/ j
  46. BTN_PRESSED, //< most important
    9 I3 p' C8 E3 V$ @- }
  47. BTN_PRESS_HOLD,# @% s1 p6 F% ^! R
  48. BTN_EDGE2,
    ( g  q5 P7 A5 l- Y* t9 ?
  49. BTN_RELEASE_HOLD,
    4 L5 h  `; {% f5 l
  50. BTN_RELEASED * w$ h  a: O" }& m  }- m
  51. } BTN_STATE;3 J& P0 p6 C2 M4 ?- d
  52. , k, X/ F/ x3 a: ?# l
  53. extern u16 Timer4_count;
    4 `1 H0 |# ?% o% X7 O+ s/ q' J
  54.   b7 a% u% q+ M4 G9 X4 s5 E- Y
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);
    . y9 Y% U7 u- }) V
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount);
    0 [+ k- ?' x4 Z/ T: Z
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);
    ( R6 Y9 [/ l" m( a; P% N$ Y6 N: l
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);( [# p, L2 R+ \$ C

  59. 3 _; S. ?. A7 I: v% R* C* N6 b
  60. , K7 t0 p! p- i! d
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码

  g9 K, L. r5 {

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

  1. /* USER CODE BEGIN 3 */
    4 ~2 [5 ^6 D7 s* H+ ^" p+ p% W
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){$ b8 k& e6 I5 Z1 K9 w1 r" Z
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);5 S& X5 O/ P4 H4 L& l
  4.     }1 m+ V0 y6 `( Z
  5. $ i$ G, [6 O4 S
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){3 P: y# C- i9 n* [: `
  7.        while(btn_getState(&K1_BUTTON_150mS));
    6 E, _0 n. f# f' _# e
  8.     }1 C, V3 D% i3 A% q1 W% l
  9. " i% T& w' @  T* J" w% i
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){
    " O+ x7 z. t/ ~. K
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);: b& J! Q! E) A  F6 c. g
  12.         HAL_Delay(150);
    " Z* h, `2 b3 e+ ~2 B
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ; E' J/ u8 \1 W5 q& z) G$ r
  14.     }9 b# H4 B2 h7 h" Y, H
  15.     HAL_IWDG_Refresh(&hiwdg);
    0 E& Q/ z; g! e5 P8 @' G& N
  16.   }
    % Y* P7 K- _2 N8 m$ N
  17.   /* USER CODE END 3 */
复制代码
! B# h+ R  x: D- y; X0 Z6 d

测试结果OK。


8 {3 y2 [5 J* W

6、软件复位
4 b% W7 C0 J% ]; @9 P  O
  1. /* Private user code ---------------------------------------------------------*/
    $ L8 l1 z2 g" K# q
  2. /* USER CODE BEGIN 0 */
    - D9 p- r- V0 r1 d% `4 f
  3. void SoftReset(void)( y# T; _! s2 p0 N! E# G
  4. {
    7 ^; ^& k. p4 y) L
  5.     __set_FAULTMASK(1); // 关闭所有中断# L9 I, i. U7 Z: q( Q$ Y  z! v/ v
  6.     NVIC_SystemReset(); // 复位
    1 C) J& N$ l( }9 q  O
  7. }
    0 a' q' F" e4 e% z+ O; @
  8. /* USER CODE END 0 */
复制代码

! `- T8 H$ J6 u; Q, f$ N- @
8 ^# f) L+ M7 R. F' R5 o4 s9 a8 ?6 a

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

  1. /* USER CODE BEGIN 0 */
    % M! Y+ T4 g4 t( ~
  2. void SoftReset(void)  J- O  }) ~5 |3 E3 H) k
  3. {: F& A) m2 ?$ \& j. w" |) Y: c, q
  4.     HAL_NVIC_SystemReset(); // 复位
    7 s* m9 [/ Z. Q* U/ \0 Z/ ?
  5. }
    $ N+ L! G* d# X" B1 p: Y- {' |
  6. /* USER CODE END 0 */
复制代码

4 c% n& |' Z; z0 w* P7 c2 `, x6 Z+ f& u

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

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


: |+ x7 G' J1 B: I$ u

转载自: 矜辰所致

如有侵权请联系删除! L: r+ Z* R, ^$ x+ G, X& N" @

" A+ p2 L- {  `: K1 C! I7 n6 e3 i2 W
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似分享

官网相关资源

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