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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);9 n2 i8 k% d: y% E
  2.     HAL_Delay(1000);
复制代码
0 N$ J; z+ d" G" ]# A5 F

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

4 Z+ x6 _) |* t

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */
    ' `- T/ l8 \. t  y7 w% m- L/ s
  2.   HAL_TIM_Base_Start_IT(&htim2);! `8 X3 V. V) u, d
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */9 @7 z  G1 D  ~
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    6 N( Z/ K% I& P% |5 ^/ I* q$ v
  3. {* W4 X5 u% Z: O: q* S, y( I
  4.   if(htim->Instance==TIM2){+ |+ W' t* y) P
  5.     Timer3_count++;
    , l- B7 p9 G. t
  6.     if(Timer3_count >= 3){: u0 k( B8 j1 r1 u  O$ n
  7.       Timer3_count = 0;7 p2 ]7 i) t4 K  J& @- n
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);    & w! i& ~' o$ \0 T# p
  9.     }, z* H9 I' {- K, C
  10.        5 c! m$ \  ?# Y! ^
  11.   }
    ) k$ S5 l3 r8 j  q! e- `- m$ P* h
  12.   else if(htim->Instance==TIM21){' f& H; f( r% @3 ?9 Z4 ]' x+ ~5 H5 G& _
  13.     ++Timer4_count; $ P* d. e- t4 }  Z
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;    - x3 k5 r- d1 k% V) ~
  15.   }2 A) ^4 w$ o' G- j! T1 a
  16. }
      q$ e5 f5 w, d
  17. /* USER CODE END 1 */
复制代码

4 a# g2 D8 ~+ @2 c9 K2 C4 S3、串口相关3.1 printf函数的实现, ^: T; a+ ?- ~4 z& s
  1. /* USER CODE BEGIN 0 */, {  S; ]1 t6 m4 _( V7 k. F
  2. #if 1; m) c& v7 O* u
  3. #include <stdio.h>
    * s( i& U& O2 ?
  4. 1 a; ~; r* ^/ J& P3 l+ P/ V
  5. /* 告知连接器不从C库链接使用半主机的函数 */& }/ G- V' e/ G0 p6 M. X. K4 |' G
  6. #pragma import(__use_no_semihosting)
    5 x; @# A1 d6 P! G/ z* A6 s
  7. . h! A4 r+ c( ]. z7 a
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */" }" _, x) U+ W5 C
  9. void _sys_exit(int x)& U; O. y, N5 o4 U7 g
  10. {
    5 ~$ d, N% d6 c  T7 N& u
  11.     x = x;. k- V9 d- T+ S3 C( I2 U
  12. }
    * w) n5 m$ ]% R3 M! f
  13. 8 i/ `# ]' D( B( M
  14. /* 标准库需要的支持类型 */8 U3 [" p# |, V1 q
  15. struct __FILE
    " e% k$ L  q) N9 j0 e/ C/ L
  16. {: x9 i9 g0 K4 ]& q* H! P
  17.     int handle;
    6 [& t0 U2 S# c% Y# y8 }! \0 O
  18. };4 |3 V: ^  e) i
  19. 9 p, R. I# G6 k
  20. FILE __stdout;
    . }# G3 R* T5 }5 K
  21. , n$ h* ?. W0 N; f1 F
  22. int fputc(int ch, FILE *stream)
    6 y7 h) ]3 v# ^9 U  T9 y/ r( H
  23. {
    & N4 a' T, Z. E( ]. P, M
  24.     /* 堵塞判断串口是否发送完成 */
    4 P1 o! J9 ~* r: ~3 K  E
  25.     while((USART1->ISR & 0X40) == 0);3 r1 p# \7 C7 R( ?, Y

  26. 5 s! j4 R% {. x1 O+ c
  27.     /* 串口发送完成,将该字符发送 */
    : h( _" X) @% [+ V# F6 r) m
  28.     USART1->TDR = (uint8_t) ch;' M: c- [) D( K  |8 Z
  29. ) X* r# D0 v- o7 C. t: ~$ y
  30.     return ch;. K- a0 C5 j7 Z# X/ l
  31. }
    2 o. a- j* H4 D$ [3 K
  32. #endif
    ( r2 _' c& P" Z& @) Y
  33. /* USER CODE END 0 */; h. i$ i- K; S- s& t/ m0 b
复制代码

3 O0 Y0 y# b3 I% g$ [$ a) E- {" Z8 H- e5 }$ j( N

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

' {9 i" t! o; S7 W1 w( ]

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

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

  1. /* USER CODE BEGIN 1 */) k* s8 Z- ~) U: n" X4 n
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    3 J. j' z0 V% }
  3. {+ q5 \; j2 \7 B4 `- l) r4 v$ ~6 p
  4.   if(huart->Instance == LPUART1){
    9 M! ^9 h  g* [" U
  5.     Enocean_Data++;. {4 y' s. I3 j; N6 J
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);1 ~! A+ a. ?' i  v; I1 J4 a
  7.   }
    8 n3 B- ^" d( ]' \' W0 l
  8.   else if(huart->Instance==USART1)
    . @7 r. [9 O% o  @/ C+ N
  9.   {# ]  l* G+ N/ E4 ^5 ^% L
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); 9 e' Z( c5 s9 k1 I% o
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    3 P: w3 j  Z/ H- _( n' h0 O7 p
  12.   }
    4 J1 D# r- T- Z
  13. }
    + P  H0 ?/ Y9 g8 w; z
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */4 V5 F% _% v4 E! N
  2.   /* USER CODE BEGIN WHILE */' T* U& q& U7 K3 B/ _" S: I6 [6 U
  3.   while (1)9 q, ^4 w4 S6 K; V! y" Y* H  N
  4.   {
    / `8 d- g2 r! l6 t% q- d
  5.     if(test_data != Enocean_Data){
    . _  n3 C% @- |; Y
  6.         HAL_Delay(7);
    " D. r3 ~7 m& S' N8 [; x# U
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    ' l7 i% F% F1 N9 F& V# n
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区
    ' N, z5 X5 s5 t0 Z$ h  |% Z) H
  9.         Enocean_Data=0;
    3 H7 Z" I  v, S6 O3 d0 o
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错- y, ~; T5 ]9 c' }9 g
  11.     }- U  q* [3 [: ^& b# t& Y( Z
  12.     /* USER CODE END WHILE */
    - U( p2 V& k! H9 D* b
  13. - S, ]4 q5 l6 P: S, d
  14.     /* USER CODE BEGIN 3 */* V( `( ?, ?5 J* j* I
  15.   }
    - U4 @* s! A; \0 p; h+ `
  16.   /* USER CODE END 3 */
复制代码
2 N7 L/ }0 x  o$ [  P

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

  1.   /* USER CODE BEGIN 2 */# }3 o% j$ _( E: F; @7 V. a% d
  2.   HAL_TIM_Base_Start_IT(&htim2);, E+ M+ l  V5 M8 k7 S  F& N5 {
  3.   //使能串口中断接收
    2 O- D' Y  E$ J1 J
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);
    0 q* g6 M0 K, G5 A5 H
  5.   /* USER CODE END 2 */
复制代码

' y6 o5 ^& T2 j# v6 W

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

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


3 f4 i( M* f. n, @* _

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);) X7 l& M# T! v
  2.   }
    * E$ @9 t8 H5 M0 a6 X- Z. Y% `) C
  3.   /* USER CODE END 3 */
复制代码
) i4 {0 d4 n2 T# r: X$ _3 H* Q# i

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

5 j' V# B; `& G; N! H' e9 o

5、按键驱动移植

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

  1. /*$ p0 c0 A. T) U* a
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下2 }7 p3 z1 @8 s" U7 W0 B, f) y
  3. 和以前单片机项目按钮方式类似  - l8 c9 o; Y, t8 ?  h
  4. by  qzh, B/ y! v* ]# c$ R7 G
  5. 2019/8/30  1 h% J; x+ @, t4 ?  u5 J
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发* r4 t( ^5 I1 T" Z) j
  7. by  qzh( a0 e" E* {3 V( v
  8. */
    7 u  ~$ {" U9 G7 S2 U0 Q
  9. #include "mod_button.h"' b8 e8 }7 ^7 {# b) U) A

  10. ) j* U  G! X( W+ X: _9 `; J& Z

  11. 8 n; ~, q* D# u
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
      Z; v0 l1 ]* b5 q. y) n: j
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)
    % J  I( s( J* `& `3 q$ v& ?
  14. {
    # E; `6 f. |4 P) V/ T
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);
    6 M1 l! B) n" x% |" z- G
  16. }
    : e4 G4 ^8 ~2 L, e. z' i

  17. 0 d6 L+ c. C8 r4 n& [9 W$ j+ _) c
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  
    - s$ h" ?8 i2 m& \7 o
  19. {
    + y- b, h! T( O% ~
  20. // __HAL_TIM_SET_COUNTER
      p$ l& A' S8 E9 q7 k1 b2 V" x1 K8 C
  21. HAL_TIM_Base_Start_IT(&htim21);+ K* \: I8 ?. T/ A
  22. // HAL_TIM_Base_Stop_IT0 c' A7 x/ h& f4 ?: Z0 X
  23. // TIM_Cmd(TIM4, ENABLE);& X6 W% i+ Z2 R! Q4 |, ^
  24. if(pu8timer->on == 0)  j9 y5 n& ?6 W7 Y  }
  25.   pu8timer->on = 1;
    , y: u6 K" r' R3 r& p& r
  26. if(pu8timer->on == 1)) [& x" i6 t$ X" y5 J. y, ?) R) S# H
  27.   //IntNum = 0;
    8 Q6 E* o8 t. ], B# d/ Y
  28.   pu8timer->timeInit = Timer4_count;
    3 b* f+ C$ }; n4 I; V$ n
  29. //pu8timer->timeInit = IntNum;
    2 i: M, ]8 T4 A! @" x' D
  30. pu8timer->timeOut = 0;( i4 ~: c9 n  k+ h4 i& y
  31. pu8timer->timeToCount = u32timeToCount;0 |- t  Q7 ^0 ~+ E) l
  32. }
    3 p2 D1 i0 o% s" }6 H

  33. 1 a, r6 y& P6 S: z2 b5 P
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)4 X% a6 U# ^+ X& {3 I3 g' ]
  35. {
    " Y5 O+ b, X: g/ l* ?
  36. uint32 Temp_Val;
    , R* H. Q3 w& ~' d7 M
  37. if(Timer4_count > pu8timer->timeInit)7 m. e5 ~$ t0 g3 o* r9 I% V
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;. C0 I9 S1 \  i% a( H( O6 [' ~
  39. else
    ' V$ A) X# x( ~% s2 ]* [/ d
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;" N. `9 n0 N. j" K
  41. if(Temp_Val >= pu8timer->timeToCount)
    + ^7 a8 a9 Z5 }2 X4 H: r
  42. {5 e; R  g7 c, |. F; K; s' V+ C+ R
  43.   pu8timer->timeOut = 1;6 {9 ?) o8 e2 [( \
  44.   pu8timer->on = 0;% L* s/ G1 q1 U! a: P+ T- B
  45.   pu8timer->timeToCount = 0;
    0 D6 [, ?7 o! M0 ?& E
  46.   pu8timer->timeInit = 0;
    " A. e2 C( i6 v/ \; A2 Y
  47. } 7 Z0 S% c' q8 Y( U% y0 Y/ n& U
  48. else 7 U! X, F% q+ {; P" a# P2 l$ n
  49.   pu8timer->timeOut = 0;. _; D) S1 `8 [0 ]  }6 G
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;/ X  ?) I# d3 `
  51. }- i. d% z, s2 J( v1 H

  52. 9 J- z, {" U* X1 H! R4 h& Y
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)
    ; W1 e0 {6 v2 \7 m6 Q
  54. {
    / e7 i$ j1 p# \
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,8 _  h9 l$ k9 ]* v2 z! \
  56.           5, 2, 5, 1,
    1 R6 @5 I( S1 M7 |* k  w
  57.           7, 2, 5, 3,# X" X/ k: q* v* F' O* {
  58.           5, 4, 5, 4,
    / F  h5 Z% I. H" I9 L3 C
  59.           5, 4, 5, 4,4 _$ [4 y. }$ @( T0 |
  60.           6, 1, 0, 1,
    . S- i! U$ O  c, ]5 ^
  61.           6, 1, 7, 1,
    - i6 {2 H1 z4 \8 N6 K
  62.           0, 1, 0, 1 };
    ; k' Z3 ^/ }3 w* _

  63. / C( y/ B9 s0 \: k* `, n
  64. //register uint8 u8Input;
    ) j# h* X2 |" E1 y
  65. uint8 u8Input;
    3 s3 Q6 i+ \3 r0 y$ m2 C& C# z
  66. // Get button state
    ( L9 O' j9 _; J$ @9 k% t
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);1 P0 C) b5 D2 N- }8 ^4 x( G
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;" L% z* R+ \& @
  69. 2 q# B. F0 z8 o- L) W
  70. // Get timeout state
    : C! O4 A& @; E& Y
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);' w$ _0 x! `& }" _7 g
  72. 5 ^6 O! T7 u4 Q
  73. // Get new state+ U9 o+ w0 D9 S' D% X
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action
    ( T/ v) Q$ {0 ?: x
  75. % q8 D' A$ I0 v( o; m# M
  76. // Perform action 6 X& Z, s% V" e0 |( R. }
  77. switch (pBtn->u8State)
    , C0 T/ N; ?( C# t
  78. {, m! ]/ h# u0 z. T5 ^. H
  79.   case 1:. m# B3 q: A  H6 K
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);* l) V& P) k" x5 N4 X8 i
  81.    break;+ W4 L. L8 s: X
  82.   case 5:3 k# r$ t2 a. t. w, w( B
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);3 l. [8 [% p$ y7 q4 a5 ]6 H
  84.    break;
    ) o( N6 r6 h' R/ Y
  85. }) c$ ?/ F: R. q% u2 L" S* [) S
  86. // return pBtn->u8State;
    & j; h" ^1 e- F+ d
  87. //待测试+ R. r& o" s! ^+ v, t! u- Y
  88. return (BTN_STATE)pBtn->u8State;
    1 q" H- ^/ C; R& P* l* a
  89. } 6 i- B! w0 Q; B# u, d

  90. # R8 ?( o$ I% O4 [7 Z1 Z
  91. 9 w; L! ]+ }  x
  92. void Button_Action()
    / ~" u9 q# y' M/ Z+ v  o# Y
  93. {
    9 M2 }- C0 W2 R' _
  94. /*( k' e5 ]. k% \) R3 E
  95. 按键动作,模式选择: H% t2 |# G1 l. X5 i' c( w# d
  96. */
    0 F: G  S- x, t
  97. }- r7 q; \# b' J* M
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED
    : z2 ?' N; l9 @1 p% [! ?
  2. #define _MOD_BUTTON_H_INCLUDED
    5 s0 ?. p! F  x. z
  3. , _0 [( |5 W; {4 r) ^6 j) |
  4. #include "main.h"4 Q7 i5 p, k* ]5 @# G$ j( H3 D0 S' c( J
  5. #include "Datadef.h"
    8 {) G! j: o) D" X1 Y% x5 X  y3 F  v
  6. #include "tim.h"
    # C% S& G, a& E- N8 r$ O& [$ M4 \
  7. /*
    " L+ R" Z" j( h( D9 c
  8.        Timeout ON# o9 x# j; |# a0 F3 K# I
  9.                 _______|_____
    * w4 ?: y, `4 Q9 ?
  10. P             |             |    Timeout OFF6 W6 w) ?$ F" b- G# a9 L2 t9 R
  11. R  ___________|             |________|____8 M9 g! W+ Y0 b# f
  12.   ^      ^  ^    ^  ^  ^   ^    ^
    & R9 Q/ b* [1 R/ ?% x' ]& i
  13. S  0    1  2    3  4  5  6    7
    & u, ^  R  H1 B2 v" ~" A

  14. & m! p# a- K4 C4 ]' U' p7 N9 m
  15. P - pressed, R - released, S - BTN_STATE7 X* r( e6 b: O
  16. */. x7 p& x% l6 N6 M( M& w

  17. , X6 W7 ^/ m) |* @
  18. /*
    ' m* F8 D; {4 W# E7 ]1 @- [
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6
    ; B$ O. w4 z  S
  20. */  D; d5 [! k( N9 m7 J7 i9 I
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND; S$ b+ Y) a1 B$ c* f2 Y. B' [
  22. . g# {; r) s( K3 l7 h! k8 c4 J

  23. , ~* W/ z$ l. h! e0 j
  24. typedef struct* b9 r) s8 w: W# n3 j# T
  25. {
    1 x+ R8 Y1 A1 Z% f+ A1 n& w% f
  26. // Public
    6 v5 `0 `) t6 K, p3 w5 @
  27. //uint8  u8Pin;   // e.g. ADIO06 T+ n0 d3 ]2 L* s
  28. //uint16  u8Pin;   // e.g. ADIO0; ]6 F4 k7 ?$ B/ @! `8 ]
  29. GPIO_TypeDef * u8Pin;
    " n# [  C/ Y9 g3 a0 f; |3 p' X
  30. uint16_t    GPIO_Pin;
    9 w7 f7 @# y+ D$ v  M( T! C
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState)7 X, T/ |. d7 f7 q% Q. f7 H
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed
    + g0 X5 x# @0 |3 Z! h* w: k
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released
    - a& ~+ G7 V; T9 ]6 r5 i

  34. 8 {5 {9 ?9 N" ~
  35. // Private
    : W6 A$ G. h: r7 F7 Y$ b5 H; W8 p! H
  36. TIMER_TYPE tTimer;2 K9 A' Z- ~% u" h8 A' X9 d
  37.   uint8  u8State;
      N' F) h% r  V, |# n% L6 i
  38. " i  t- m* I8 V* a  m
  39. } BTN_STRUCT;
    ! \/ Q9 n1 ~( d- _, V0 q

  40. * p' t6 R4 W% b
  41. typedef enum + M5 o: d. G" ~2 ?; j
  42. {. t2 e- N+ _2 D( F8 ]+ a
  43. BTN_IDLE = 0,
    7 R2 a. `/ r; _7 O6 i
  44. BTN_EDGE1,
    7 G$ S) g9 T8 g6 m* ?' P- y% O6 p
  45. BTN_TRIGGERED,* @* Z8 j9 H& Q' R, h9 T
  46. BTN_PRESSED, //< most important0 x( I! }" V2 w/ f5 Y
  47. BTN_PRESS_HOLD,
    ) f% l1 K; p+ M- R( J
  48. BTN_EDGE2,
    8 A& q+ T5 U) h: T. X& u
  49. BTN_RELEASE_HOLD,: X/ j$ t7 y6 a5 r4 n' F
  50. BTN_RELEASED
    - H# z/ q+ R% c6 P$ u
  51. } BTN_STATE;/ y0 L* S) f5 i5 ^$ u- Q+ H# j  |3 a
  52. 2 W- M: T8 L0 \# u
  53. extern u16 Timer4_count;
    5 J" |& y* l" A  z

  54. * ^, @9 n1 {+ X0 P
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);: }7 W* g. b" O  Z/ s
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount);
    % G7 K& _2 Q, v2 |) I
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);( `# A, {5 Y2 H, l8 _( x
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);
    - }2 n4 B- H5 W8 Y9 T% k
  59. % `9 u" j  C# n7 O3 I5 x: I7 p
  60. 0 O+ ?' `- ]% y; w7 k
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码
9 K# m' R; c' L( D% w; s8 D/ z3 `

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

  1. /* USER CODE BEGIN 3 */) K1 h, U0 ~5 O! ^1 r
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){' u; F, U9 f& U3 k. |7 j' W$ ]( T1 p
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);* u0 z7 @6 U8 C
  4.     }* D& P6 v! g5 \( T8 \" e
  5. / `; |- T6 r. c; F( K; H! N% p' X& H) f
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){
    9 {2 G8 }7 ^3 A8 T8 Z
  7.        while(btn_getState(&K1_BUTTON_150mS));
    " X, r6 l0 A! ?+ D
  8.     }
    4 o' b5 I+ N5 U! b. ^
  9. 5 A) o% O) \$ }( P
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){
    5 r0 A# H$ N0 c: Q+ Q- ?
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ! X8 \! X( `8 e3 g5 m6 d) D. S: c
  12.         HAL_Delay(150);9 h7 t8 K# `9 ~
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    2 c6 Y* P) ]% H+ b
  14.     }
    0 u; `  D$ `) Y7 J( e, W
  15.     HAL_IWDG_Refresh(&hiwdg);- j  b% _+ \* j0 n' Y) D/ n
  16.   }
    5 Q% r* f8 E( ?
  17.   /* USER CODE END 3 */
复制代码

, Y$ r- }9 |# {! F+ j, A

测试结果OK。

9 ]1 m0 v0 s! b8 z* v5 y' q

6、软件复位
* z5 D8 `( u% d  ^
  1. /* Private user code ---------------------------------------------------------*/
    ; m7 p+ w/ z4 ]4 d
  2. /* USER CODE BEGIN 0 */
    3 _' n( A2 r4 r' w2 `' b
  3. void SoftReset(void)
    1 w& y9 Z8 \) I9 o8 @6 `% M
  4. {: Y7 E: }; ]1 U  a8 n
  5.     __set_FAULTMASK(1); // 关闭所有中断* i; A& w5 X; j' r* ?5 \, Z
  6.     NVIC_SystemReset(); // 复位( \  E) {, G! H" @$ y
  7. }
    - d$ V7 V7 e6 A0 v
  8. /* USER CODE END 0 */
复制代码

4 t' R% b2 S3 F/ f' Q1 H: o9 ^
5 I, }( S2 A$ a9 O& V( ?' k0 O  q4 e, C3 t

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

  1. /* USER CODE BEGIN 0 */* k) Z; Q. B8 n" u# W0 A% @
  2. void SoftReset(void)4 V9 J( T5 C; O
  3. {
    ) j* a) [! k8 C) U: a" ~, ^
  4.     HAL_NVIC_SystemReset(); // 复位
    ) @' b; j  k; m: J
  5. }* V+ P4 G" v2 o) @
  6. /* USER CODE END 0 */
复制代码
: `: W/ V, p$ I  b/ W

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

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


; {7 ]. O5 k+ p( {

转载自: 矜辰所致

如有侵权请联系删除/ X' b8 I" c# \' k3 ^

% @3 J$ i& Y6 I' _3 m+ J; q  t( r: ~
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似技术帖

官网相关资源

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