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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);8 v) _+ B2 n9 B5 l# H8 C, L
  2.     HAL_Delay(1000);
复制代码
, ?9 f, W6 r: {7 V* Y2 p

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

( `0 I/ B, E, R7 p& i. ?" P$ m" {# I

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */
    * g" S* N+ W4 K' K  S
  2.   HAL_TIM_Base_Start_IT(&htim2);. H% b! N- G' ]1 P
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */* L: Z2 h5 k$ }( t; }$ c
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    3 K! [7 J5 K( u% B" H
  3. {
    ) l' b% q* T/ j; W2 G2 d0 N% ~, Q
  4.   if(htim->Instance==TIM2){
    0 k0 U: U0 m( e3 S
  5.     Timer3_count++;
    4 }3 j4 u* k/ }( f; G
  6.     if(Timer3_count >= 3){
    ! |! O: E$ S9 Z8 O
  7.       Timer3_count = 0;: ~( G: ]& d8 M3 U* p6 M. [& b9 {
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);   
    ; U+ A, R8 a, T/ ^+ g" ]% D9 h
  9.     }
      t+ Y8 x6 z! W
  10.        % x- n2 x9 l6 `& q& i- E# a
  11.   }
    2 N6 T+ ]8 e  E, |
  12.   else if(htim->Instance==TIM21){
      }  r( J2 X$ P( n% F4 w
  13.     ++Timer4_count;
    1 W! }; _. j7 |" a! g; F( D
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;    1 M' ^; ]# _: _
  15.   }
    ' X  h& D! l& m
  16. }& {' `- B6 m3 B. M; e3 P
  17. /* USER CODE END 1 */
复制代码
! F4 \1 g! R; z6 X$ z2 v+ R4 |- B
3、串口相关3.1 printf函数的实现
6 f6 u  J! _: C6 m( P
  1. /* USER CODE BEGIN 0 */  r3 v) m4 V; Q% Z3 g% U* D. e
  2. #if 1$ t  P" m$ M" O% [/ {" g
  3. #include <stdio.h>& I* Q! n8 o$ }( l: d: d

  4. - w* k( z& C$ [7 ~  V' e& N& |
  5. /* 告知连接器不从C库链接使用半主机的函数 */
    / q9 C1 u. E) ]
  6. #pragma import(__use_no_semihosting)6 r) z/ S4 F) \3 q4 [
  7. 5 B6 B" y7 F7 E0 Y, r4 g
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */0 i) x( g* K9 }+ G
  9. void _sys_exit(int x)0 L5 k! `5 |3 v! D
  10. {( O! W" S. U! Z% T9 {# |2 q" O
  11.     x = x;
    / x7 ]7 F$ g" M% d& K
  12. }7 q% M/ X$ ?  v) P# f" p9 c
  13. " d" q% h, k6 h
  14. /* 标准库需要的支持类型 */
    ( J* _; E5 L9 T' i8 [
  15. struct __FILE0 |& J9 R, q7 Z2 Q( Q
  16. {
    9 u8 m" j( _6 M, E# x
  17.     int handle;# {- b. n/ E) ~* d
  18. };/ K6 o) G1 H/ P( a) v
  19. " T1 j  H  @+ _. M( y1 U
  20. FILE __stdout;' e4 s- Y+ D6 ?& B4 e

  21. ; d2 t# O. ^4 N
  22. int fputc(int ch, FILE *stream)1 j4 Y) N, b# T% d: M; e
  23. {
    5 }+ @6 w/ m9 c9 Z
  24.     /* 堵塞判断串口是否发送完成 */5 q- Y4 j  e5 m3 P' L
  25.     while((USART1->ISR & 0X40) == 0);' b" [1 D5 T% u& n% c
  26. % r8 [1 z6 g. h7 j
  27.     /* 串口发送完成,将该字符发送 */- U4 [* w, U; W" @
  28.     USART1->TDR = (uint8_t) ch;% m) t+ {0 F+ G6 i  P; F
  29. ; R! h7 K3 p9 ~% I$ _9 `
  30.     return ch;
    ( X+ }6 O& D2 i  v3 S3 W5 S
  31. }
    : W# @& a" B3 ]/ [7 j! ~  p9 b8 V) ~  h
  32. #endif' T; S% l' E* N( g7 L* K% [: s. a
  33. /* USER CODE END 0 */( g& d1 n/ n' X6 o& e
复制代码
6 y1 K+ ~) S; O8 c4 ?
2 s) T. e$ ]! F' J# i5 p( u; |

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


! ?! m3 E0 V" ?1 n$ g6 G

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

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

  1. /* USER CODE BEGIN 1 */
    + H- |+ v+ G6 J$ K6 h
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)3 Q; U7 y0 l& Q8 P5 X
  3. {
    ; ~  A/ F3 v) T. r
  4.   if(huart->Instance == LPUART1){
    ) x5 H8 z0 @1 \% ^2 y  S' Z4 N# g2 f
  5.     Enocean_Data++;( ?/ v& @  Z6 K. i& U
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);: j: K. i: c: J0 Z" z7 j
  7.   }
    9 s; T# a* i7 m6 _6 s
  8.   else if(huart->Instance==USART1)* b' s* J; E% J+ S/ a: U7 K' i
  9.   {  }9 A6 S% E' N' B: H& ^
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); * I; _- w- N$ z# @  I5 D, a1 S
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  
    6 ?* R( D: K& U& o5 c' a+ D
  12.   }
    5 j$ d+ V$ \& Q; b& M& Z
  13. }
    3 A8 x4 K: }* [$ m! j1 m
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */
    % [/ P- W  _3 K5 q0 F
  2.   /* USER CODE BEGIN WHILE */
    1 [+ C' c! D  s* _
  3.   while (1)
    $ A+ I( f7 [7 l. a' E' Y* x8 o
  4.   {
    7 T- i9 S# o. a7 j+ x, G+ x
  5.     if(test_data != Enocean_Data){
    # ^1 A; @$ `' _; ]
  6.         HAL_Delay(7);
    $ N* L$ r! l; e, t
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   : f6 n% P& R2 \* F( l( `
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区 % B1 @6 h. `7 F5 N- o4 t2 z5 E
  9.         Enocean_Data=0;. E: z; [/ G$ s5 L5 d$ `
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错  S- _3 Q% w: w, p' \1 a2 R
  11.     }6 s  n$ q; }" d0 c! T4 O
  12.     /* USER CODE END WHILE */
    " K8 v) o) @' _* o$ S

  13. " w. l- k6 ^3 j; n8 w6 G: R
  14.     /* USER CODE BEGIN 3 */2 g! a6 C1 O7 D3 A% x
  15.   }
    6 V/ W; s9 s. |
  16.   /* USER CODE END 3 */
复制代码
. N  t  h1 F- b' P2 a# `/ T' y

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

  1.   /* USER CODE BEGIN 2 */& j1 t0 z, ?, }, x) B' O7 K
  2.   HAL_TIM_Base_Start_IT(&htim2);. b3 G. c. A9 O7 W  G- A4 w
  3.   //使能串口中断接收
    & x+ `- t1 ^! ^' O, D( `
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);& V3 }5 f# J% t# o
  5.   /* USER CODE END 2 */
复制代码

' `' w- c! [$ l' G

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

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

' y: z4 i, Y+ a

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);
    0 y! k( O6 n$ e# \
  2.   }1 j, b* X; M" j$ @# G7 K- U
  3.   /* USER CODE END 3 */
复制代码

5 U) ?& B% {+ t, R

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


4 ~: T( B: x( @

5、按键驱动移植

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

  1. /*
      R" H. G2 C+ o
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下* m& B1 B  E( R. i, n) f  n3 d! S
  3. 和以前单片机项目按钮方式类似  . c1 J! z. d) j2 t! i
  4. by  qzh: Z% N+ p+ S, ?0 u% I
  5. 2019/8/30  & Y4 n/ i. [( _. C" Z1 e' Z
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发6 d5 P7 B- c/ B0 i& A  j( [
  7. by  qzh! v# i$ n- R/ A* x" l
  8. */8 g' b( k# X8 w3 Z
  9. #include "mod_button.h"
    : Y1 j4 _, ?% [& I
  10. 8 Z; ]. b- O! {3 m7 L, g' q
  11. : }, d; V# r* S. N/ F
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)0 _* w) G) E1 g! A' ?
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)
    ) x) h9 L) `( W. O% T
  14. {
    6 ]8 n# i6 x/ w; `( d. A. L
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);* j. O3 W! K' M; m3 X" S0 _
  16. }
    ; v6 b# |, x, E$ x

  17. + e2 N- P5 h1 d( p% s
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  5 y9 p* @) ^; k6 S
  19. {1 Q4 P+ b: a! F( \0 |
  20. // __HAL_TIM_SET_COUNTER
    : k- P* }& I, ^7 B. z
  21. HAL_TIM_Base_Start_IT(&htim21);
    ' p  {( D* w" n# j
  22. // HAL_TIM_Base_Stop_IT: F# D! B9 u6 b  C2 @. u
  23. // TIM_Cmd(TIM4, ENABLE);
    + L9 c! o) E: p: w, ~' X, m% l
  24. if(pu8timer->on == 0)) ~( p: V, t' X$ Z" L
  25.   pu8timer->on = 1;
    7 E* f  [$ J  u) n
  26. if(pu8timer->on == 1)" a7 c& m+ K5 J0 y, l
  27.   //IntNum = 0;
    1 {! R2 F4 q6 I; W$ C9 f
  28.   pu8timer->timeInit = Timer4_count;( A9 H& ?8 R$ k
  29. //pu8timer->timeInit = IntNum;
    + Z: `( h' Y* X9 _4 T! P1 D
  30. pu8timer->timeOut = 0;4 Y  g  D- s" E7 M. E
  31. pu8timer->timeToCount = u32timeToCount;
    9 D- \0 w8 x; C+ J
  32. }
    3 ]# \3 p# _& `6 n4 c; W4 p5 V
  33. + V6 |0 n! ~: @0 a2 T5 C
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)
    * i- D' P+ ]( C; j; P' F
  35. {
    : }. q5 |5 D: t; T! R
  36. uint32 Temp_Val;
      U% C/ ^; F# \6 B3 A: o
  37. if(Timer4_count > pu8timer->timeInit)
    + m" e  [% q+ o. p* ^- s; z; u7 O
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;& f+ W1 j$ ?* E. m0 i. T
  39. else
    6 d7 e8 B9 d  ~" Z$ g
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;  o7 Q& Y+ h4 n4 U0 h- V
  41. if(Temp_Val >= pu8timer->timeToCount)4 J/ X2 a- H9 x- V4 `1 `
  42. {4 i  [( L5 w" `( U
  43.   pu8timer->timeOut = 1;& d! ^1 w0 l  G8 }7 X& S. Q5 S. v2 c
  44.   pu8timer->on = 0;
    6 t2 A( z/ B0 Q! |
  45.   pu8timer->timeToCount = 0;+ p$ U+ D# B2 N9 X; ]4 \' n
  46.   pu8timer->timeInit = 0;
    4 w; s- p4 I. G7 V( e2 Y) Q. [
  47. } * {  D& M2 i+ }0 T* P- B  a
  48. else # [  k4 ]8 _" P+ m. ~
  49.   pu8timer->timeOut = 0;
    $ m1 K( F$ B: p" E
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;% k2 J2 ?" U$ q$ c% q! A" `
  51. }
    5 b/ O+ U3 b( D% M: i
  52. 8 \0 z  _6 c8 A
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)+ x# A$ _, _. g* d' p
  54. {
    % u+ a7 E7 `. P/ m! B! {  y
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,
    $ h9 g) i8 Z6 E& ?2 K8 X( g2 x
  56.           5, 2, 5, 1,
    $ r( b( ?, ?5 F+ o! b
  57.           7, 2, 5, 3,' f/ M+ x  K! Y6 `' C: M
  58.           5, 4, 5, 4,
    " O+ ^; i4 o5 i( C
  59.           5, 4, 5, 4,
    1 `7 A1 c; b8 w7 C$ L
  60.           6, 1, 0, 1,
    8 B$ H2 x; ^& X# C. m. L
  61.           6, 1, 7, 1,
    , o% \: I' h' e
  62.           0, 1, 0, 1 };" ~$ C: ~1 R0 R3 j( I2 c) V
  63. ! k9 E4 E$ \/ F0 }' V& r
  64. //register uint8 u8Input;
      V# z  r/ f7 S$ \: R
  65. uint8 u8Input;: C& c0 a5 i6 D7 A( d' f3 }3 @6 v# U
  66. // Get button state
      ~1 p) S, @8 ?+ H
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);
    / N: h" z/ u2 s" u
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;% \) R( x& S' i
  69. : `! D5 I; c, y( S5 B
  70. // Get timeout state
    $ q* k! j$ Y! b$ f" @! ]
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);! G  z. v- e# {' J6 u5 `

  72. - O( o+ p- m) _5 a8 `
  73. // Get new state
    6 g) z' m1 q' P3 v- c. G; H% s% B
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action( @! N7 t$ z6 l1 r9 A1 F! u% u' F

  75. , C  E8 H# Y  D
  76. // Perform action
    + s$ G6 @- w' r+ M2 {- ^1 {
  77. switch (pBtn->u8State)2 j4 H. @3 ?, K  o0 I! Y' B
  78. {, |( X: Q, n7 Z
  79.   case 1:
    # v# F3 s4 J$ A  H! ?
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);
    7 |" x0 @) K5 D9 u; I. u
  81.    break;! f- G3 O& i; ]/ W: x' E0 J: m
  82.   case 5:
    + G$ M* E% @/ s8 r( ]) y
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);* v6 K. ?1 ]8 n' p
  84.    break;
    . @7 i1 t4 t. h6 g0 [: q
  85. }4 o. _* a8 C7 z& p' C; i# k
  86. // return pBtn->u8State;. P* W' P+ |" F) I% a- X4 d$ p
  87. //待测试
    : l) o* z8 W; B" j
  88. return (BTN_STATE)pBtn->u8State; / r$ R5 k. \7 o" |7 Y; Y3 t
  89. } ( }' Z/ {6 G1 i" S) H( r

  90. . Q  h/ K1 x4 V( w1 n5 c7 f
  91. ) n# R! ?6 E4 u6 `3 b8 _& H; I& x
  92. void Button_Action()
    1 y6 d# {+ }. R  u4 {) y- n6 S
  93. {5 o* o3 q. K- I* v* R5 C
  94. /*
    5 F  S7 \- c5 J1 m2 u  n
  95. 按键动作,模式选择; b% X# F5 T% l1 g4 [8 ^# y
  96. */
    3 J4 F" a% B2 \: D1 j
  97. }+ a  Y# t: D, u' O6 t* C1 \
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED
    4 h6 A$ o1 H& _4 a3 G) [2 S- i
  2. #define _MOD_BUTTON_H_INCLUDED% T, k  x) K0 Z+ n  ^8 v8 B
  3. # E$ L2 n% \: O7 [  N6 I# L- O% l
  4. #include "main.h"' R/ R! t) H/ \4 d( n6 P4 q, |1 k
  5. #include "Datadef.h"
    . c* m' X/ d6 f$ l  {& s& \/ g: v
  6. #include "tim.h"+ d( I& d4 w1 K- S: P
  7. /*
    ; f  J/ y: R* C+ A
  8.        Timeout ON
    6 p  ^. z( {% `9 n
  9.                 _______|_____8 D8 d5 a7 f. C  l6 [6 y
  10. P             |             |    Timeout OFF
    $ n& t/ \  a0 f0 K4 \
  11. R  ___________|             |________|____
    # f/ ]9 {5 J1 N8 x* M
  12.   ^      ^  ^    ^  ^  ^   ^    ^
      U, r8 w+ a) M3 J+ @& K! f
  13. S  0    1  2    3  4  5  6    74 }, ^: F; k6 M' P
  14. ) h& S: j% P5 z, [$ k: L9 `5 J
  15. P - pressed, R - released, S - BTN_STATE
    % ]- S' ?0 X( [1 J
  16. */
    ' J; D5 \8 Q& k: h' G

  17. 3 R9 W( T1 U! b( m" ^
  18. /*" T% ~$ R7 i! v0 l( g3 ^1 y9 B' q
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB6' s) {+ c9 ]3 P3 q4 P
  20. */  l$ _% ~- t+ h. B+ f
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND4 p6 J$ _6 Q8 N% A! L( C$ ^
  22. ; y" G* S- a+ D5 ~# ^% v% T) _
  23. 9 K8 Y. [) F; ^- N4 D9 c4 M6 y
  24. typedef struct
    8 m0 c2 Q7 w: |
  25. {9 _( X) n+ N1 e) f" r
  26. // Public - h4 ~( Z: p3 i! H* w) C/ i
  27. //uint8  u8Pin;   // e.g. ADIO0
    2 G# D+ S5 P( |9 l* t
  28. //uint16  u8Pin;   // e.g. ADIO0
    ( y0 x. `( p& T1 Q
  29. GPIO_TypeDef * u8Pin;
    9 i8 H2 p8 j/ Z' [
  30. uint16_t    GPIO_Pin;; V7 I  g0 k+ x  m
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState)$ `8 e0 e3 X1 T5 }4 L$ Z
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed+ f) b" l0 b  s6 ?
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released
    5 ^7 q4 w; w: ]' o3 P
  34. ; ]8 U. u  X# j  D/ A$ m
  35. // Private( T: R+ h5 K' F' a% ]' Y4 K; `  G
  36. TIMER_TYPE tTimer;
    0 R) Z3 K% h) d
  37.   uint8  u8State;
    * q+ g  q$ x* l6 o, n

  38. ; n- ]7 j9 w. j+ A
  39. } BTN_STRUCT;+ d5 k, y; e. |, \) [$ ~7 T

  40. . s# ]( S7 j$ U, b
  41. typedef enum ) t4 N% Z  D, Q) F, L; ^$ T9 o
  42. {
    % s; s0 ^2 X. C  ?5 v" q
  43. BTN_IDLE = 0,/ e9 O4 J1 b0 X; I0 g8 e, K
  44. BTN_EDGE1,
    7 ]; j, Y& L$ t( `. g  r! `
  45. BTN_TRIGGERED,- N3 H9 i& K- ^: w1 s% s
  46. BTN_PRESSED, //< most important
    - s6 m( s5 `9 z9 \9 N
  47. BTN_PRESS_HOLD,3 c( B1 @" D/ w& c/ ^
  48. BTN_EDGE2,* _4 p) y5 n9 d% `
  49. BTN_RELEASE_HOLD,
    : q& u7 b: b. r! Y/ a: s# ?' M
  50. BTN_RELEASED
    9 X7 ~8 {' ~+ W! `' S1 C$ \! K
  51. } BTN_STATE;7 s; p& V7 {% y

  52. - c4 r. l0 T2 t0 m8 i% H  o# T
  53. extern u16 Timer4_count;/ e5 z4 k7 C7 Y# k5 p" X

  54. % H1 d3 ^! R; m1 w  m4 W) m) b+ I
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);
    ! {. l% v: ?2 K/ K) W5 E
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount); 8 ?/ l( e( \6 k- J% C# |) h
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);1 t& m& M- J% a
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);) z0 U* I0 E4 O& V; w+ }
  59. ! X5 Z& T* R. T- x; Z+ R. C

  60. $ u) `  M* B6 K
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码

% C; H3 p4 w7 _& W! p& c  A* N+ |

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

  1. /* USER CODE BEGIN 3 */
    7 B- p, N3 R& o# ]- V! y6 z& x  m$ s
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){$ H/ M% A- Y( n# `1 S: X
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ( G2 x4 A$ l( {8 \3 w$ D
  4.     }; {6 q3 o5 k2 m6 D( Y) I" z
  5. 9 F7 S. B+ }: t+ b
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){4 E5 |: {6 x* G& K/ h
  7.        while(btn_getState(&K1_BUTTON_150mS));
    3 @& f; Q0 u. S
  8.     }( Q$ T; v# S3 ?! c( F

  9. # \2 x% ~. ]9 S0 T; R2 [
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){; V% v/ k! f, x$ `2 M1 S
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    2 D1 \# `/ F1 F2 s: `8 _) t
  12.         HAL_Delay(150);4 N- z6 ^( B3 T' M$ w" O2 X+ j0 D
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);, j- i7 Y7 H$ M" L2 M8 J: @, ~# n- P
  14.     }
    5 S: F$ s; A5 n4 ^: S" m: g0 r) e' ^
  15.     HAL_IWDG_Refresh(&hiwdg);3 a5 c4 E, N/ h, K( \  H) _
  16.   }
    7 N3 S2 y+ ?& M: y& f
  17.   /* USER CODE END 3 */
复制代码
: C) @# q+ x( A2 U

测试结果OK。

/ ?! z& z- I9 `2 B2 l( m1 H

6、软件复位- F7 [( b5 G) a1 t
  1. /* Private user code ---------------------------------------------------------*/
    5 h7 y7 A0 U5 z) S% o
  2. /* USER CODE BEGIN 0 */8 i0 C6 M8 y5 G3 G/ u$ K+ S6 a# ]8 K
  3. void SoftReset(void)9 T/ r& R! J" @' M: s. k5 d
  4. {
    : y& O7 |1 ~0 S6 q, ^
  5.     __set_FAULTMASK(1); // 关闭所有中断
    2 Y3 M2 h& G( n3 b0 M0 q$ u4 @
  6.     NVIC_SystemReset(); // 复位
    : ?& U- z, O8 d% F
  7. }7 ^# ]' w# _$ Q0 p8 H/ Y
  8. /* USER CODE END 0 */
复制代码

; u8 g: z' Y' f1 w
) s5 F. v# S  v8 }5 _

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

  1. /* USER CODE BEGIN 0 */
    0 z. O/ j% \* M8 D' t. |
  2. void SoftReset(void); Q6 V! ?) N5 {, {- m+ a# Z& q
  3. {5 O2 e; Q6 R' V. w5 v8 a( q
  4.     HAL_NVIC_SystemReset(); // 复位
    , D/ O  v+ W4 w  n" ^3 f' b
  5. }
    % U0 f' j; S$ A
  6. /* USER CODE END 0 */
复制代码
! U3 n3 w/ Y2 o+ K$ q0 k. w0 Y

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

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

& ^; c. v9 u& q7 a

转载自: 矜辰所致

如有侵权请联系删除/ p9 s3 n* Y+ S! ~# w" Y+ R
7 j7 J, R! \3 Z" p1 U* n
( f& O) u' z2 l1 y8 C* S
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版