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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);5 k2 m/ i/ U  y) X* i
  2.     HAL_Delay(1000);
复制代码

& g, n1 x9 k7 S4 ~, @: H

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

- C" q$ v) I( W, J% _

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */
    % M3 q. P  _4 T) ]' G
  2.   HAL_TIM_Base_Start_IT(&htim2);5 H  L: g. _9 }, `+ j4 _  Z: i' i
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */
    6 g% k3 v0 L# C2 g
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)' A  c9 B) K8 X$ l4 W, G5 h& `
  3. {
    / i6 S/ [1 \8 t$ Z
  4.   if(htim->Instance==TIM2){
    5 R- L2 C5 {6 K/ g4 ~( o
  5.     Timer3_count++;
    - E7 a5 X9 }4 z( J6 }) I& O' R
  6.     if(Timer3_count >= 3){4 {. J3 C( ]% A0 Y
  7.       Timer3_count = 0;4 B0 _$ E  x/ n) l# ^) x
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);   
    8 H1 [4 H% Q7 A: ]$ E" g
  9.     }
    1 ?. [# {! m2 D
  10.       
    - T' w, G4 p- N& c* L0 X4 x
  11.   }. X$ ^% P5 L: C  g% y
  12.   else if(htim->Instance==TIM21){
    " M" X; T8 P9 C5 k: V" F
  13.     ++Timer4_count; 4 y% h. |! S) E: d2 m& }) d& U
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;    , l- ^- U9 c; G2 x8 U& p7 y7 P
  15.   }
    % w! o1 s4 u- Q  p  \1 P' M
  16. }0 m2 b. B1 y+ k+ J  C4 F
  17. /* USER CODE END 1 */
复制代码

0 R. m" d3 I+ f- N7 V* N, `3、串口相关3.1 printf函数的实现
9 Y! X& |0 y$ z- b, n; k$ h! t! V
  1. /* USER CODE BEGIN 0 */. S# n+ G' y& \4 s+ x; m! [
  2. #if 1- V4 w! J& B6 P, @$ V+ N( M4 T/ z
  3. #include <stdio.h>* ^" P' ^8 V; {

  4. 6 A9 |6 n& o* C9 Q- A2 f: Y' I
  5. /* 告知连接器不从C库链接使用半主机的函数 */
    . Q* Q; C# Z! V5 U" c3 n; q
  6. #pragma import(__use_no_semihosting)
    0 }: I; X8 y4 f
  7. 9 L$ c" i, v% k1 c3 j* p/ @
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */3 ]: Y0 I2 q3 Q4 d3 n0 Q# ~
  9. void _sys_exit(int x)
    ; {! L0 k8 Y; g' z9 U  ~
  10. {
    . ~) Z+ z6 ?7 C! x
  11.     x = x;/ O) y: S1 R6 A
  12. }
    6 {1 _3 B$ v) }! ^+ s7 F

  13. * p# B; h9 I* y0 c0 j
  14. /* 标准库需要的支持类型 */# m1 i+ W) }+ K3 \( c" g5 Z: ]1 [
  15. struct __FILE. y: i* y: x+ k7 S- f; y' ?, {
  16. {* S- g! W( ^$ ~  w6 M( G" G2 W2 K
  17.     int handle;0 a4 `5 Z% N. L' f2 b
  18. };: }: N0 [( v( t% U* m, R1 l  ]
  19. ! L' T: y0 L/ h8 G
  20. FILE __stdout;% q8 c1 o6 c. y0 n, J  t
  21. % n$ M9 J, t5 ^- T0 ?9 w1 i/ I1 b
  22. int fputc(int ch, FILE *stream)
    % k3 ?& |0 h! s
  23. {
    5 f& @) B" p8 J3 ^* f; r9 L  z
  24.     /* 堵塞判断串口是否发送完成 */
    ( L& j1 `) m( @" z/ `
  25.     while((USART1->ISR & 0X40) == 0);
    % \$ d' B$ Y# \  j. J- ~
  26. # D: e/ C' H  Y5 M- Z; D1 @! f! S
  27.     /* 串口发送完成,将该字符发送 */: f0 k+ e2 T/ N& Q0 H7 w+ e
  28.     USART1->TDR = (uint8_t) ch;2 j9 ~7 r: [7 a. C8 ~" t
  29. 7 k, U+ \) h# w3 f8 a7 D
  30.     return ch;& j. {# t+ _2 a. v4 {0 O( J
  31. }
    % A3 Q8 D! \& g7 u
  32. #endif# g7 g- ?+ @! z! V
  33. /* USER CODE END 0 */- d9 X% K9 l  m9 ~  c2 A
复制代码
  O/ A) J  w+ z
( ^& M( R' v1 Z9 J. i

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


1 h& j# ?% ?7 [0 }) S

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

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

  1. /* USER CODE BEGIN 1 */
    # V4 \8 C3 \. h2 d  t
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    ; d; ?( I- d1 B! F5 `8 M
  3. {
    . V: _0 H+ V  [/ M7 w, |
  4.   if(huart->Instance == LPUART1){9 U. R/ t9 U0 T
  5.     Enocean_Data++;
    ! ]# C9 _# U& t2 O' b6 [1 `: ]5 m
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);. X  C( n% v  m
  7.   }
    7 G4 T  S' X' a6 v
  8.   else if(huart->Instance==USART1)" S% X& M9 H! k, a2 u6 ]' |
  9.   {
    . v0 _  I5 Q3 S1 O% u, z
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); 0 b9 x3 {5 V1 z- M
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    / p+ m9 `, l9 n- m8 F, a" z. z/ h
  12.   }
    ( f- Y5 b$ _0 }3 ^) ^
  13. }9 h2 k- [% I* h# o
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */. U$ ~  ~& W; F7 w6 H* R
  2.   /* USER CODE BEGIN WHILE */
    . o7 f2 T0 {& r& u: @
  3.   while (1)
    ! j3 G4 e% w& W
  4.   {! R' B" O9 X% ^( r
  5.     if(test_data != Enocean_Data){
    1 l* r, e7 _3 C* Z. K
  6.         HAL_Delay(7);
    8 y3 w8 u  q  [2 b" K$ g
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    2 i& [) ^7 C4 ~2 a. ]. d
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区 1 D7 o, A! w/ T3 x( u( f7 U$ g
  9.         Enocean_Data=0;
    : t) C: R2 |( o1 {1 R, v: ~5 h" k# j
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错2 q' ^' n: q9 W, w
  11.     }
    ) M; V$ \  V7 c( X* [" z
  12.     /* USER CODE END WHILE */
    % _, M4 K& ]9 t2 K1 u& [

  13. 0 F# g- o! w2 ?) Y4 B5 K
  14.     /* USER CODE BEGIN 3 */7 {) m5 W+ U' f, l7 n# a4 H
  15.   }0 I0 h8 @. m: V
  16.   /* USER CODE END 3 */
复制代码
" p% y/ J) H& G

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

  1.   /* USER CODE BEGIN 2 */8 Y/ \& r7 }7 [* Q
  2.   HAL_TIM_Base_Start_IT(&htim2);9 @/ P. s$ k6 w1 e
  3.   //使能串口中断接收( |. Y' Y8 d. p9 ~0 b0 |
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);
    9 `( \( _- z, j0 Z6 v3 ?2 f7 ~2 x5 i
  5.   /* USER CODE END 2 */
复制代码
) h. ^) i/ |2 g' c

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

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

. f& A& _0 Q& x1 t

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);* z" X% R* s! E, M# n/ p. m
  2.   }
    ! [& H4 j5 C9 ?: m  j- @8 w) D3 H
  3.   /* USER CODE END 3 */
复制代码
6 i8 Q6 I5 d- `" [; d" d0 r

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

6 X  t& u  M$ |" F; P( C

5、按键驱动移植

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

  1. /*
    ( K& m+ ^! \+ @7 {0 U* v
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下
    0 v; c' A2 z' l) q
  3. 和以前单片机项目按钮方式类似  % o- n! q$ W& S0 R- {5 s
  4. by  qzh
    - M7 d3 y* W& Z1 U
  5. 2019/8/30  
    - ?+ ?0 y3 ~- F2 e4 B+ R9 \5 l
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发+ ^" `$ P1 h- z) m# ^# R
  7. by  qzh! B  z  q6 S; [1 ]8 T0 W
  8. */
    4 p( ^* |& f* ?
  9. #include "mod_button.h"
    ) P* O+ M" ]3 X6 o3 C6 ^

  10. ; y' W2 _. _2 p3 M
  11. 3 o0 N/ {* h  M
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
    $ D. W( o5 G7 }& M) O8 p# z8 \
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)
    2 n+ _: I" ~) |6 n9 M: {# d& a
  14. { " }9 F+ l& s2 I/ `
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);
    , C( v4 _- ]9 O4 m% l
  16. }
    + c% L% a, I! B7 Q& x  g" O- N: Y
  17. - O6 P/ h; x! H" S
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  
    . w; K% ^) k: }
  19. {- g. B# C5 m- F
  20. // __HAL_TIM_SET_COUNTER- A: Y- }, h& u" W3 M
  21. HAL_TIM_Base_Start_IT(&htim21);
      C' M8 e- |! U. d1 H
  22. // HAL_TIM_Base_Stop_IT
    & m5 n% U1 r. S% r
  23. // TIM_Cmd(TIM4, ENABLE);3 D# ]% g0 ?! c8 J- ?* j+ d% h
  24. if(pu8timer->on == 0)
    : P+ h" J1 w; o- R
  25.   pu8timer->on = 1;
    ) ]0 c. b$ X" X2 y( B' B
  26. if(pu8timer->on == 1)% ^6 l' U% S4 X5 p5 p8 t. P  _
  27.   //IntNum = 0;/ `. ^* g1 v" J
  28.   pu8timer->timeInit = Timer4_count;/ @& e9 W% u$ I2 I5 y5 @( N1 x
  29. //pu8timer->timeInit = IntNum;9 I/ @* Z: O, ~$ L
  30. pu8timer->timeOut = 0;
      i4 Q5 a, H) o6 b% f( h
  31. pu8timer->timeToCount = u32timeToCount;
    / g/ x: D1 m3 U( H3 P
  32. }
    + D5 u- c+ Z, a; K% F/ o
  33. 5 W! D3 |& z6 f) _
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)
    % |  Q4 @6 U2 x# E
  35. {
    5 M% o# g5 i$ O8 |: b& [
  36. uint32 Temp_Val;1 L, u' R% l9 t  T# ^
  37. if(Timer4_count > pu8timer->timeInit)
    0 W4 g. p, Z% W8 K0 v4 b3 }& W* N
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;
    & G( O* X/ b6 D, p
  39. else
    . k# X* o0 t2 X" B! I' B0 G  m
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;
    ) |2 Q! F8 f5 l- x5 ]' L
  41. if(Temp_Val >= pu8timer->timeToCount)6 Z( D* j! _% N, W8 `9 _0 u/ e. F
  42. {
    + G7 a$ R2 ?; G  K1 ]% E* o
  43.   pu8timer->timeOut = 1;7 z* C0 n1 g5 N' E8 l/ r
  44.   pu8timer->on = 0;4 u) r9 C9 L& K$ b/ `
  45.   pu8timer->timeToCount = 0;
      ^3 Q6 a! s9 Z$ o+ }" Z( ^& \" ^
  46.   pu8timer->timeInit = 0;
    + `' b* b7 m+ f: j
  47. }
    3 X$ v1 j' v6 f. p+ Q- J
  48. else
    % @" h* b3 c8 O* B
  49.   pu8timer->timeOut = 0;
    9 H" _3 I( l& \8 M
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;, R4 Q* n9 j4 f0 ?! B2 i3 E
  51. }
    ; N9 R  s- c  U  r
  52. + p$ w, t7 B7 B4 L; a) `5 i8 ^6 O
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn); Q; {0 U; u0 V0 E
  54. {
    / b: P# Z# B8 e4 U* U+ r" z1 o5 B' ~
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,' E% H% I4 ^% U  |, T
  56.           5, 2, 5, 1,
    5 r4 f7 D: e2 n' |1 |# s+ l$ e: u
  57.           7, 2, 5, 3,
    & v( X3 y# m6 }. T
  58.           5, 4, 5, 4,
    5 h# r6 `* [' a2 d/ m. y# t# v
  59.           5, 4, 5, 4,
    # y5 \: o4 ^0 `4 v
  60.           6, 1, 0, 1,
    ( ?5 ?9 T# j+ Y. o) y, c
  61.           6, 1, 7, 1,' R1 d% H6 O  G  L8 T
  62.           0, 1, 0, 1 };
    - |2 h9 `, i0 b% n1 U9 ^- Z/ l( {
  63. ! j- _, N/ }9 @( Z( u
  64. //register uint8 u8Input;  ?) @9 N9 p) d3 E0 D/ X
  65. uint8 u8Input;
    * U7 L3 J0 ?- \' i  ]+ O
  66. // Get button state" g5 ^3 i+ j$ W
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);% M) o$ \8 B; o1 e  X/ \8 ?) h" f  ~: P
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;
    " [; _; r; @) ^5 v: r0 M
  69. , n2 A2 r1 e; }4 `% S! S
  70. // Get timeout state4 P' _/ n' I2 H2 c1 ~
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);; I" m# U; a# @
  72. ; X( L% {- f, n; |% g
  73. // Get new state
    , H1 m/ U% c; X
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action8 Q4 ]7 q% K3 P6 Z) C8 H7 r3 m

  75. 8 v. [8 `0 I2 u9 a
  76. // Perform action 4 E; V0 Y/ [; n: b
  77. switch (pBtn->u8State)
    2 ?9 Z" N) I  o6 l. Q% B
  78. {: T8 r6 Q1 q, b! s* x- x  ?0 l  W
  79.   case 1:5 C& R' f4 L2 y7 E+ z! T* w
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);8 f$ d; Z! s: v+ {* q
  81.    break;$ M3 F: a9 a% N( N9 v
  82.   case 5:
    5 Z( m0 e+ l- O
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);
    0 A7 [+ ~. D4 y
  84.    break;0 |& [" D( j! v  ]+ t
  85. }
    4 A" M1 P! r( b2 L% _
  86. // return pBtn->u8State;8 ^4 v4 }$ Q  r6 w1 V. f
  87. //待测试0 z. ?  C( w% h; H& O
  88. return (BTN_STATE)pBtn->u8State;
    * g9 k5 L  L5 Y" F" L2 G$ c$ I6 Z- s
  89. } 6 x6 u1 m& y  P. F9 K

  90. , J; n. u. n4 A! }

  91. # H2 W6 N3 {, l1 q8 o
  92. void Button_Action()
    / R2 ]; r& g1 [: l, F9 _
  93. {: |6 h2 L+ W7 G  N& A
  94. /*3 `$ |2 q3 V$ |. ~9 c, h6 p
  95. 按键动作,模式选择6 c8 b- ?+ S& ?
  96. */6 ?8 \5 q! ^1 _
  97. }4 _. A. R/ A1 v; L( P
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED- j  A0 \* E$ x# I. n0 P
  2. #define _MOD_BUTTON_H_INCLUDED% [' @8 l0 y. w5 u; w5 r
  3. ' }3 Y2 U  z' A
  4. #include "main.h"6 I: A) W) E' k2 Z
  5. #include "Datadef.h"
    , B: ^2 c) R3 K% M* X  j$ i
  6. #include "tim.h"( ?7 g# @# h( Q5 ]3 [0 N; T* l
  7. /*
    : M* J% O# j- V8 P( ^6 t4 A) r, n9 s
  8.        Timeout ON
    / f4 B) \* i6 ~. N! }- X8 _8 e
  9.                 _______|_____
    + W: n6 g1 V% e% v
  10. P             |             |    Timeout OFF
    3 a. ~4 k$ Y) D/ W+ M9 x
  11. R  ___________|             |________|____8 H8 b( c. i3 Y9 s
  12.   ^      ^  ^    ^  ^  ^   ^    ^6 Q0 l: B& k8 O+ Y/ u; x  D  x
  13. S  0    1  2    3  4  5  6    7) C2 t/ A- J- B9 z+ l/ A" _
  14. 3 M4 O: `* \% J" W# ~
  15. P - pressed, R - released, S - BTN_STATE
    : ]( A- H0 l5 i6 L
  16. */
    ( W- {, \! k$ F0 H
  17. " e+ _: W. r2 g- h
  18. /*
    ! |! ?; o* y/ ?# @. d4 w% Y
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6
    4 i7 C, c0 @# d5 m5 N
  20. */  E/ ]* l, X& ^+ L
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND) v* q% P+ n9 U5 t) q: L6 a( l

  22. % O- _5 d, Q4 P; G

  23. 8 q9 w* A* x* @( A  E. u6 z. w
  24. typedef struct# R$ U0 m' }0 V8 |
  25. {* |$ l" I. I5 J7 H' p
  26. // Public
    : b+ ^) r* D* [  @/ {3 z. v
  27. //uint8  u8Pin;   // e.g. ADIO03 o3 w, B1 K7 m4 c" H
  28. //uint16  u8Pin;   // e.g. ADIO0
    1 e! ?6 R; C1 H2 z0 Z! v
  29. GPIO_TypeDef * u8Pin;
    + o% y$ v  W" y0 r1 i8 a4 S
  30. uint16_t    GPIO_Pin;* Y1 t8 r  f8 V- u% W
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState)
    0 [2 S) T$ S1 m
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed
    1 t, [9 H+ x* c) @9 q5 |  ]
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released& i' D3 A7 z- o; B2 ^' I% a4 B4 ^* H
  34. + O2 m+ E( [. f$ K- E
  35. // Private! u6 t3 M7 s; _$ R, s' B5 W! K
  36. TIMER_TYPE tTimer;) g- t' T( P  g% ?
  37.   uint8  u8State;
    7 \7 y) M) j- Q' c' r+ V
  38. ' E# G" X3 m+ y, F9 T+ S
  39. } BTN_STRUCT;0 h& p- _9 s9 i) A9 k
  40. & J! n7 u1 t9 p  M1 j
  41. typedef enum
    % M6 k( F2 N/ {/ \" P, R8 W# z
  42. {: `, }1 U4 ]. |- h( c5 x
  43. BTN_IDLE = 0,9 }# @9 A. i; w5 V2 |
  44. BTN_EDGE1,  Z) ^6 K6 W8 m  g8 j
  45. BTN_TRIGGERED," p" K8 D3 c- V! `- G
  46. BTN_PRESSED, //< most important$ \3 ^# E. D6 L( Z& x* n
  47. BTN_PRESS_HOLD,
    / S% `( }+ A2 q" \' l3 z, v
  48. BTN_EDGE2,
    2 @. C( r% _' g, z* B' E/ X
  49. BTN_RELEASE_HOLD,5 f( }, c, d/ s9 y2 N" k
  50. BTN_RELEASED
    , U4 B0 B* ?  h% u4 m( J
  51. } BTN_STATE;0 w' u: B8 t: n6 i2 U& h  ~
  52. ( o+ s; F* x) S# ~
  53. extern u16 Timer4_count;/ s* N& z& z% Q* ]" F$ u1 {8 Z. M

  54. 9 X/ O' h2 S+ U+ C8 N3 j
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);
    5 v2 l) V( f6 l: t
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount);   d  `0 ~( r1 B; u, ?
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);2 I. c. v7 s2 H" S
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);' s& A+ \. V" t9 n' W7 c" V0 S

  59. / M' v" Z" u5 p$ C

  60. 0 p1 e" u8 `1 `3 P  ]% i  a
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码
" q7 L/ F0 v' s: I7 x+ g

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

  1. /* USER CODE BEGIN 3 */
    2 y. f* n  O: ?
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){
    - z9 A: m! W: G+ K8 L! a/ ^3 ]8 T' @
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    7 k" u  E9 b5 Z$ B* U- |- y* }. G
  4.     }
    % h: b8 a5 N! \; P: F2 M$ e- Z) Y
  5. / I8 x4 U; [7 F, J, o6 @
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){
    & D( i' l; p) c# N- U( |
  7.        while(btn_getState(&K1_BUTTON_150mS));! N9 _# o/ s% i) z- n
  8.     }6 H' o! @- L" A3 i$ N3 k

  9. 1 h5 _- d$ L% R9 r. y, s) A: z/ ~, P
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){
    3 d: m& C! \/ E
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    " _5 B8 f( Z: e& N- x6 D5 @
  12.         HAL_Delay(150);) m' d1 P0 o) M4 s  I. ^5 K. Q8 Q" _
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    4 M, t$ j, Q# G) f" e! q
  14.     }- D7 U& y: c) z* t( m( N0 }! D
  15.     HAL_IWDG_Refresh(&hiwdg);
    ! F: B8 K9 m' ]' E" w- b9 E3 }! |
  16.   }0 v' Z' \+ j" k, Q& n0 V
  17.   /* USER CODE END 3 */
复制代码

& M1 B& \% ~% C3 ]6 q" L8 W$ t% H

测试结果OK。

" l. h; ?6 \3 \# H. f

6、软件复位
; Z9 t. e# e) y+ s. r
  1. /* Private user code ---------------------------------------------------------*/6 y6 B" n3 Q0 S( M# I' V, |& g
  2. /* USER CODE BEGIN 0 */
    / z' I2 d7 W3 U+ U
  3. void SoftReset(void)( `. T9 g# j) J/ }* D. r8 l5 L" ^
  4. {
    : B% ^4 ]/ T; c, e8 N  _3 ?
  5.     __set_FAULTMASK(1); // 关闭所有中断
    , g# g& I% l$ `
  6.     NVIC_SystemReset(); // 复位) y; Q4 ?! v2 m! {
  7. }/ n& ]3 r, X8 x. @3 o" H5 C5 t& b
  8. /* USER CODE END 0 */
复制代码
6 j3 k/ N; L% v

$ D5 V9 y8 j& f& e

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

  1. /* USER CODE BEGIN 0 */
    , n, `% s8 T) K: l0 L# N
  2. void SoftReset(void): B+ C/ ]7 q. ]4 a5 a* c
  3. {3 s% q" K$ T/ a6 F. a
  4.     HAL_NVIC_SystemReset(); // 复位. v: N* d- @4 G: N
  5. }! X1 j4 W$ k+ k/ K. ^. b+ @
  6. /* USER CODE END 0 */
复制代码
' X/ f0 N3 Y* i( W7 _5 a

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

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

3 {( |( E" s2 u7 m

转载自: 矜辰所致

如有侵权请联系删除2 _3 ]( `8 N8 K' [  G; d. Y
1 N! f% o% M; V+ H

+ ~7 e. H/ Y8 g5 X
赞 收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似技术帖

官网相关资源

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