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

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

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

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

  1. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ; }$ {9 g5 B7 Y, ?
  2.     HAL_Delay(1000);
复制代码

: b% m" d$ K3 ^% ?

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

7 i+ l) e3 Z  c% s/ A0 ]& T

2、定时器控制LED闪烁

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

  1. /* USER CODE BEGIN 2 */- t' u4 N* d7 |( w! ]3 V
  2.   HAL_TIM_Base_Start_IT(&htim2);
    & k+ W: z* \' g. m, x6 l
  3.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 1 */
    3 U/ w6 l+ w( L. n1 q. c9 X8 Z
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim): H) F, z2 B1 H
  3. {( ?% C( l& J1 c1 g! n7 i. }
  4.   if(htim->Instance==TIM2){
    " O; {1 ?; @8 r! W# k
  5.     Timer3_count++;# z3 _& G' l( M) T* j$ y
  6.     if(Timer3_count >= 3){
    $ b' J% [$ L. u0 U: W) e+ i
  7.       Timer3_count = 0;! h7 m, s, x7 l3 F
  8.       HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);    ; e+ [3 M& z, }# m* |1 \
  9.     }& d" v% u# I' d6 l
  10.       
    # t2 O% f6 N1 p( I8 a( \
  11.   }8 R& h1 k, W6 `# x" g* L; I# |
  12.   else if(htim->Instance==TIM21){! V  h! l  y0 d- T1 [2 D
  13.     ++Timer4_count; , y# w: O* {8 E& W4 P7 \
  14.   if(Timer4_count>0X1FFFFFF)Timer4_count=0;   
    8 r' d& S/ l$ [. i) I! f& h) r, C* B
  15.   }
    / L$ v& n% e5 M! b! ]! N; v
  16. }
    / k% [( Q3 I# V
  17. /* USER CODE END 1 */
复制代码
5 H$ f* o3 H5 [1 z# d
3、串口相关3.1 printf函数的实现! [( J  q( \* q* o, R
  1. /* USER CODE BEGIN 0 */8 R8 G, n. F5 i) \" t1 S
  2. #if 1! Y2 M4 Z7 i# ~( A2 N
  3. #include <stdio.h>6 I1 C/ F/ B) ~
  4.   O1 C1 }4 t% @# D9 @" \0 f5 G
  5. /* 告知连接器不从C库链接使用半主机的函数 */
    8 R( K9 s4 A; V$ Y2 B0 X4 O2 N1 }# Q
  6. #pragma import(__use_no_semihosting)
    : Q3 g4 A6 X# {; ^
  7. 4 m7 ]" Y) F' L7 e4 h5 x: j. R
  8. /* 定义 _sys_exit() 以避免使用半主机模式 */8 z3 q3 H2 q1 M: Y; h
  9. void _sys_exit(int x)* U+ G7 Q2 K7 T8 K- j% L
  10. {
    # {2 k0 ^6 @! J- a+ ^
  11.     x = x;
    # z  S# d5 g, [' s3 P
  12. }
    4 R1 ?; X- d: A5 X4 ~$ f' L

  13. * t9 x& L% p2 R3 ^
  14. /* 标准库需要的支持类型 */+ ^  n0 e7 }* l+ N
  15. struct __FILE$ f2 E3 x6 Q% U8 V# [
  16. {
    ( F  n# o, ~- s' y' {/ A
  17.     int handle;6 T( Q& C' ~' f9 A& N
  18. };% u0 i* W# _9 p, M! l

  19. ) v. |% ?, u& x
  20. FILE __stdout;; h; i* s) L/ S9 U

  21. 3 U3 ~& n4 i; M% d; r
  22. int fputc(int ch, FILE *stream)6 K. F6 a) G0 {& n$ b2 U5 i- K& l
  23. {$ |( ~1 N% d! y
  24.     /* 堵塞判断串口是否发送完成 */
    1 q5 i4 o8 O) |9 u: L/ m0 u7 A' ?6 E
  25.     while((USART1->ISR & 0X40) == 0);9 _" w3 t; z1 r. [# C8 r$ h

  26. , u5 ~! }8 I5 j) t; }4 p) J
  27.     /* 串口发送完成,将该字符发送 */4 l3 P3 l: ]! h+ X
  28.     USART1->TDR = (uint8_t) ch;, Z- F3 ~: H( E" }
  29. " t* d3 ?* M) g
  30.     return ch;
    * O% ]  ~! n8 u8 L5 V6 s
  31. }
    " g: d* _  n8 l* ]6 L% L$ w
  32. #endif
      }# I. o" d& B' _, t5 N  {' M3 M
  33. /* USER CODE END 0 */
    8 N% }6 w1 J6 c- s5 l4 k! N
复制代码
( X2 D2 ~& e# z/ z9 c" }

' L) y0 V- L, E* B- \, {6 f

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

" c! c/ b4 C% G' U# o- Y% W* D

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

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

  1. /* USER CODE BEGIN 1 */
    1 U' k$ c* @& S2 Y  b
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    7 x  F7 `- }3 m0 v& [) {  Y. J3 H
  3. {2 N# o7 Y) a% R! M. w8 o9 O
  4.   if(huart->Instance == LPUART1){4 n8 x8 G2 H" e; N$ a2 d% T
  5.     Enocean_Data++;0 G" R4 H5 N2 j3 O1 _1 o
  6.     HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1);9 g1 Q5 C' B+ Z- v4 w$ `7 _7 h
  7.   }
    2 a0 R+ y  j% b1 P  F
  8.   else if(huart->Instance==USART1)
    3 J2 S: p* j# d# D8 g
  9.   {
    & |$ C3 |% \. k3 J% w1 I) k
  10.       // HAL_UART_Transmit_IT(&huart1,(uint8_t *)USART1_BUF, 10); 3 g, h, Z. p7 G3 V% B! m
  11.       // HAL_UART_Receive_IT(&huart1, (uint8_t *)USART1_BUF, 10);  ' d# \+ h3 m; T: A% @
  12.   }& i  l- W. u4 q+ K
  13. }  J8 ]/ ]/ Y  ?6 Q3 l
  14. /* USER CODE END 1 */
复制代码
  1.   /* Infinite loop */
    ! m5 B/ Q% c, {3 V: W
  2.   /* USER CODE BEGIN WHILE */
    ; t2 x' N9 `5 R1 a) Q
  3.   while (1)2 |. X/ ], y  \9 A# G0 _/ O( @
  4.   {
    , [* z$ K, @/ K% P
  5.     if(test_data != Enocean_Data){" ?3 G/ D6 F6 v
  6.         HAL_Delay(7);
    . Q6 k5 o" f* W
  7.         HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF);     //将串口3接收到的数据通过串口1传出   
    & q5 H- j3 U; R' @& O& s
  8.         memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区 0 z8 i. l9 }( R% S! i
  9.         Enocean_Data=0;; s  a2 M/ z1 l5 R
  10.         (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//这一句很重要,没有这一句,后面接收会出错9 m, b1 @& i" p$ K3 Y
  11.     }
    ) P3 H0 e( w! `+ G; H
  12.     /* USER CODE END WHILE */6 [5 d. v+ q6 E5 ?

  13.   h/ o: X& e# a/ d9 d
  14.     /* USER CODE BEGIN 3 */2 [. a7 j  O3 n( g! A* V  w
  15.   }+ l4 ~& m9 Y) e6 g5 V+ i4 X
  16.   /* USER CODE END 3 */
复制代码
; z: i) u6 d) n) d

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

  1.   /* USER CODE BEGIN 2 */5 L) w  C+ c' ~' Z; @4 |5 k% n
  2.   HAL_TIM_Base_Start_IT(&htim2);9 `) G( G. V8 ^. ^/ S" G5 a4 b; q& x
  3.   //使能串口中断接收/ f4 Y5 H0 ~" b& R# Y. M- C
  4.   HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);: V; B9 S: \/ Y6 [& R" Q4 p1 g
  5.   /* USER CODE END 2 */
复制代码
! S+ u" Y8 |5 k+ C" D

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

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


$ @6 s4 R" k; @  m0 q- e5 C

4、独立看门狗

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

  1. HAL_IWDG_Refresh(&hiwdg);: u0 m3 D2 m% v
  2.   }, M9 a" q, M' H: {6 M
  3.   /* USER CODE END 3 */
复制代码

7 O) ^5 F8 w# ]# ~) q

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


+ C% W" @- T1 n+ ?5 u

5、按键驱动移植

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

  1. /*) W2 m% V6 _( j1 K) G. r
  2. 2019/5/21 按键程序移植成功,以后可以使用此按键,需要研究一下
    $ _2 x9 x6 {3 O
  3. 和以前单片机项目按钮方式类似  . q. ^' l" y" E% h
  4. by  qzh# O$ V8 K, u9 z2 `. o
  5. 2019/8/30  
    / o$ q  \4 P3 J8 `+ L
  6. 确定了第三行,第一个必须是7,才能按下到时间自动触发, \8 G$ |% R/ F/ d6 u5 V8 p
  7. by  qzh$ M$ `7 ?% d# e, D
  8. */( v) A" z7 B1 X: A8 s( o, M2 s# |) B
  9. #include "mod_button.h"" ?: ]1 I9 ]& s0 s" v5 D
  10.   f7 r2 D* N4 z+ O
  11. $ `3 O7 N$ ~! `. P2 O  C
  12. //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)' M$ ~$ O) n! ?! `
  13. void io_getDigital(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value)
    + W: S" d8 c3 l$ _
  14. {
    7 M7 \4 J5 E( x) Q
  15. *pu8Value = HAL_GPIO_ReadPin(GPIOx,GPIO_Pin);4 t' I# ?4 W; T
  16. }
    , A. A) H1 S4 j) ]: M
  17. ( a4 S, M" L" p: g1 j( A( c
  18. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount)  
    5 z$ K1 M# V( b, w/ P3 y& N
  19. {
    " d, N2 U% A: u; @# Y; o
  20. // __HAL_TIM_SET_COUNTER
    . p! ^! Y3 C- T9 i& _: C
  21. HAL_TIM_Base_Start_IT(&htim21);
    : Z2 i! D# o/ B8 w1 h, p
  22. // HAL_TIM_Base_Stop_IT
    ' T  S5 b; B7 S$ w
  23. // TIM_Cmd(TIM4, ENABLE);, V& }" m/ H7 M3 ^- N
  24. if(pu8timer->on == 0)1 }$ h# k/ L( [3 f& i1 o
  25.   pu8timer->on = 1;- }- K+ ?0 Q! h2 x0 N5 v
  26. if(pu8timer->on == 1)
    8 \0 I5 v' a+ _, y- ?. k# @
  27.   //IntNum = 0;
    4 |1 u# y8 `' \
  28.   pu8timer->timeInit = Timer4_count;$ A  h. b5 Y: v, s  j7 u* _  E
  29. //pu8timer->timeInit = IntNum;
    - y& `" S$ |* J( o
  30. pu8timer->timeOut = 0;
    4 h, B9 O" c7 j- \3 ^9 Q9 c
  31. pu8timer->timeToCount = u32timeToCount;0 J1 v7 ~& r; X3 i
  32. }
    3 X" _0 [) t4 L7 L: U
  33. + m% c0 h, t/ r+ b* M- q! V7 ?
  34. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer)/ h# z% r2 W+ S' `' w
  35. {
    & |4 c2 A, q$ w# R, x8 c% c# K
  36. uint32 Temp_Val;
    " D0 ^7 [# Y, Y1 n8 v, _  G
  37. if(Timer4_count > pu8timer->timeInit)
    ) X  t" d2 O, s& u8 ^
  38.   Temp_Val = Timer4_count - pu8timer->timeInit;
    : o! r$ {. X3 F0 N0 f/ _
  39. else
    . N( N* b# l; H( c
  40.   Temp_Val = (0xFFFFFFFF-pu8timer->timeInit)+Timer4_count;
    ! h' Q0 j) _  M8 F8 _
  41. if(Temp_Val >= pu8timer->timeToCount); t# e& M/ y! D  g( K$ D
  42. {
    . q- N( e8 J* |6 o7 t7 M
  43.   pu8timer->timeOut = 1;2 N$ H8 m+ L- @* M$ H0 g3 ~
  44.   pu8timer->on = 0;
    & e3 l' m. X2 G: [
  45.   pu8timer->timeToCount = 0;7 D# ^' H; n; J' z0 G" [* f2 [- c/ F
  46.   pu8timer->timeInit = 0;
    4 k6 Z! e5 I! N; u5 I
  47. } / j& T5 [% u) I2 R) h! ^
  48. else 9 H7 v6 V- E, q+ J6 T
  49.   pu8timer->timeOut = 0;
    3 i; x0 k) m7 u  s/ U& g& H
  50. return (pu8timer->timeOut == 1)?TIME_OUT:OK;) L0 Z5 M- j. r- q; B
  51. }+ M% w( ~. U0 y* d. ]

  52. 2 M6 i; h& o% w
  53. BTN_STATE btn_getState(BTN_STRUCT *pBtn)
    . R( _8 m0 l0 h: L4 t1 g
  54. {
    . g7 j1 e3 S6 W- b
  55. const uint8 transition_table[8][4]={ 0, 1, 0, 1,2 t+ J& a$ b& F
  56.           5, 2, 5, 1,
    ) Z8 p$ s6 B! p# u, {8 n
  57.           7, 2, 5, 3,( U6 w5 V( ]$ l$ k
  58.           5, 4, 5, 4,8 x5 [, I$ y* n2 n+ [# q
  59.           5, 4, 5, 4,6 C3 O' ?* V+ W  }: j, F% \/ \
  60.           6, 1, 0, 1,
    , B2 X1 |1 a. [5 n
  61.           6, 1, 7, 1,
    1 ^0 K" _( w5 p' o
  62.           0, 1, 0, 1 };; B+ ^1 v; w; e7 H- s

  63. + t% V7 u! |9 Y8 {$ S( B
  64. //register uint8 u8Input;
    ( A+ }" f/ v; ~1 f1 h3 g* {" N1 y
  65. uint8 u8Input;. G" @) x+ Z3 N, t" T% N0 f6 f+ X
  66. // Get button state
    ) d( c% `( s- g- u8 g5 C9 C3 \8 R
  67. io_getDigital(pBtn->u8Pin,pBtn->GPIO_Pin ,&u8Input);
    ; M8 z# E0 c  E
  68. u8Input = (u8Input == pBtn->u8ActiveState)?1:0;$ E+ A( a0 X' T; f  H& s& P
  69. ' K5 {9 ~& T! y$ d5 ?4 |
  70. // Get timeout state2 M$ l3 Z, V" z; a: g% }0 ~
  71. u8Input |= ((time_getTimeOut(&(pBtn->tTimer))==TIME_OUT)?2:0);
    & N; D+ Q8 l# Y8 f  _. v" M/ ]

  72. * K, N  w& K: X" F
  73. // Get new state% `8 b# f( c: L/ q, i: v) _
  74. pBtn->u8State = transition_table[pBtn->u8State][u8Input]; // we want only the state, not action
    $ M* R( r5 Q$ c3 B
  75. 3 J: ^* ]; D. d+ C0 H' a: Q
  76. // Perform action * c+ q9 C8 c: k2 d# u/ W
  77. switch (pBtn->u8State)3 S# |% ?) ^/ W/ k/ k! t
  78. {
    1 e6 c* i# |* H8 I
  79.   case 1:; [7 U9 r0 R& @
  80.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutON);% Q6 V$ t5 D/ }+ V5 T# s0 e" d
  81.    break;! u  q6 f: w$ H. {& e( x! H$ O7 D7 j
  82.   case 5:  s( `2 J' O$ w# R8 B$ g' K& j
  83.    time_setTimerCount(&(pBtn->tTimer), pBtn->u16TimeOutOFF);+ b: v2 t$ H0 y& ?
  84.    break;
    ! p+ E$ r# U3 y7 G7 {* f: v
  85. }2 D* i% T3 Q$ c: O+ I6 p8 v3 a# l  }
  86. // return pBtn->u8State;2 u0 w1 ?+ S0 Y& R! d; k: ?
  87. //待测试' H4 w4 t# L9 z2 L
  88. return (BTN_STATE)pBtn->u8State;
    . i  W2 d: }" H- ?1 x
  89. } ; n* j3 V+ H( B" Z( [$ q
  90. ; {& U0 q( ^8 A
  91. 9 `& A8 B, K  [$ B" g
  92. void Button_Action(). W: [4 q9 ~) a( X# _& D7 b+ w
  93. {4 K: R# Y: R) e1 i/ Y' [/ T  B- ^3 h
  94. /*" |3 H9 B1 s" W' m7 z( ~  z
  95. 按键动作,模式选择
    + Q3 R8 A6 Z1 H# w7 d1 o. p
  96. */
    8 o" K! V- m2 `
  97. }
    + H$ ?' r; k. \/ A4 t4 ^! b- h
复制代码
  1. #ifndef _MOD_BUTTON_H_INCLUDED1 u1 a# v: n& ^
  2. #define _MOD_BUTTON_H_INCLUDED: O/ {* U1 X$ _* D! ?( T

  3. : e* V+ J+ D  u9 _. J) T
  4. #include "main.h"& ]1 U9 N3 s5 w  G0 j1 s
  5. #include "Datadef.h"
    8 Z4 }3 J! {3 R7 I9 R
  6. #include "tim.h"4 ~, c8 O% O* G" p0 X9 F# J
  7. /*
    + l4 `# E; n# X: @' M
  8.        Timeout ON3 p* d# H/ L) t# L
  9.                 _______|_____  C4 h% _3 }# G0 q( w( Y
  10. P             |             |    Timeout OFF( i3 U2 k( {+ J3 m, w6 e0 W
  11. R  ___________|             |________|____
    7 B% S# f( C9 y
  12.   ^      ^  ^    ^  ^  ^   ^    ^* e: ], p  x, d$ L$ j7 D
  13. S  0    1  2    3  4  5  6    7
    : K8 Z+ F1 ?/ u6 J8 o  {* |

  14. 0 C1 @* A7 a' l" v: `+ t
  15. P - pressed, R - released, S - BTN_STATE, p* x( j) a2 ]% n( R
  16. */
    5 P% A6 T4 p8 ]% G3 L  j' N
  17. 6 W& }7 o' a5 q
  18. /*
    1 c0 B) m2 x: S9 f& ~7 A2 @; ]3 \
  19. °´Å¥Ïà¹Ø  KEY1  learn  PB5  KEY2  CLEAR  PB61 C/ u/ x0 T" n, R. {0 S
  20. */
    + y4 V6 ^9 \6 m, B) N
  21. #define BTN_ACTIVE    0       //when pressed, switch to GND
    1 _5 }) V; V( r" Z

  22. & G/ G% S+ j- W, |5 n

  23. 0 Y- r/ N0 H" n8 l4 e5 \; f* a$ U5 ^
  24. typedef struct! _% k+ j% S7 E. }" z. P
  25. {( ~- y3 j6 h! [6 e$ w
  26. // Public
    : u  l! Q  l# d. U4 v; b5 d: ]3 P
  27. //uint8  u8Pin;   // e.g. ADIO01 @7 r- B( E! O' [8 o
  28. //uint16  u8Pin;   // e.g. ADIO0! j1 o" \3 y7 Y+ b4 J
  29. GPIO_TypeDef * u8Pin;
    / x/ V+ ?" e5 O- |1 M; x
  30. uint16_t    GPIO_Pin;
    4 P% f7 m5 S1 d/ T* r# \7 o
  31. uint8  u8ActiveState; // button is pressed if (io_getDigital(u8Button)==bActiveState); g% B, a+ a0 I! w# c# j
  32. uint16  u16TimeOutON; // time the button has to be pressed to be recognized as pressed) ~1 K6 B2 z- r6 z
  33. uint16  u16TimeOutOFF; // time the button has to be pressed to be recognized as released  d$ d, w  ]+ n
  34. " p$ H$ c& V' {* x: F6 A( T' R. n5 P2 V
  35. // Private5 F0 ~& [: A) q; j( z
  36. TIMER_TYPE tTimer;
    $ x: r) S1 t( s
  37.   uint8  u8State;/ a, Q7 \5 m3 i+ ~% A1 L
  38. 3 x$ o% r3 U1 A) Y
  39. } BTN_STRUCT;; S  u' K( o: h" X  P7 C
  40. 0 u8 U- I! `' K+ J" f: v
  41. typedef enum
    8 r# C  M+ X! Q, v& {* w
  42. {
    . b4 B; h' w5 H' ^8 ]
  43. BTN_IDLE = 0,
    . D2 N3 A6 A9 C
  44. BTN_EDGE1,2 w$ W  g( |1 c
  45. BTN_TRIGGERED,
    ( o+ R, M# W6 m  \- u" i4 v
  46. BTN_PRESSED, //< most important
    0 _) p# O6 @! ^/ i
  47. BTN_PRESS_HOLD,
    9 }1 j9 {: g: J6 e0 b: a1 L3 ]. D) m* c
  48. BTN_EDGE2,5 u8 m  O( l7 n
  49. BTN_RELEASE_HOLD,
    % O) a) r5 h$ h  D
  50. BTN_RELEASED
    + E5 Y. T/ b9 P
  51. } BTN_STATE;* \, ?$ Y( S' ]* M2 b

  52. 4 k" M/ G# M; J8 b5 A
  53. extern u16 Timer4_count;) @7 S3 d$ d- _- K4 ?+ W5 K

  54. 0 ^! E- C/ t  q
  55. BTN_STATE btn_getState(BTN_STRUCT *pBtn);
    ( p  ~- l. O+ j1 a* |  s
  56. void time_setTimerCount(TIMER_TYPE *pu8timer,uint32 u32timeToCount); 3 |/ U& o$ `. K5 k
  57. void io_getDigital(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8 *pu8Value);
    ( S( f* B$ l- Q3 t/ m
  58. RETURN_TYPE time_getTimeOut(TIMER_TYPE *pu8timer);
    - ~1 c$ L4 V/ i& |9 Q
  59. & @6 V" W; l0 _1 ]% Y9 B' M3 u  {' J

  60. - L5 h8 t# P5 C, q9 x
  61. #endif //_MOD_BUTTON_H_INCLUDED
复制代码
4 X0 L; G' n) O! A  L& @

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

  1. /* USER CODE BEGIN 3 */% @, H# c% S1 B/ ?7 \% x
  2.     if(btn_getState(&K1_BUTTON_150mS) == BTN_EDGE2){! F: A& U* I: {' r! ^. r; j
  3.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    ' A' K/ }2 v5 s1 D# o7 C
  4.     }
    3 y/ H  n7 B. F( q8 g$ r! e& L

  5. ( ]" e. u& o5 P3 y- g( U! d
  6.     if((btn_getState(&K1_BUTTON_2S)==BTN_PRESSED)){
    & t2 z1 {$ I" n, @$ p. o$ ?/ y7 j
  7.        while(btn_getState(&K1_BUTTON_150mS));
    + D9 D  D$ V4 K" q% |* i+ P  ]
  8.     }
    2 L6 o/ A6 m1 q9 ^/ c
  9. . t$ K  W0 L8 Q2 J
  10.     if(btn_getState(&K2_BUTTON_150mS) == BTN_EDGE2){/ b+ K( I1 X0 a* }  O+ X# A
  11.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);3 @, O0 e- k7 K
  12.         HAL_Delay(150);
    , u" t4 _8 j1 H" j- A  ?- r  |
  13.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);1 q/ |- i7 r& w
  14.     }4 U) Q1 h+ @1 M& n% i# h
  15.     HAL_IWDG_Refresh(&hiwdg);9 o* x# x" F% W$ u: X
  16.   }
    + N9 m/ L; `' A2 l) k. O/ B
  17.   /* USER CODE END 3 */
复制代码

' B7 h! y* O' n9 ?  Q

测试结果OK。


0 H1 v/ ?- I: S1 j3 |1 S0 F$ p/ Q

6、软件复位5 B7 Y4 [! S# o/ b
  1. /* Private user code ---------------------------------------------------------*/
    4 d' \# I, v6 N2 s  |
  2. /* USER CODE BEGIN 0 */1 l+ T' E4 t+ ]& Q
  3. void SoftReset(void)
    2 G5 E. [! h3 M* ]& j  P
  4. {
    0 x: `7 A7 c/ U+ }
  5.     __set_FAULTMASK(1); // 关闭所有中断
    6 Z( c2 V( B6 Q! A6 b% A
  6.     NVIC_SystemReset(); // 复位3 {; _9 }0 f9 W: S8 B$ T' a! u
  7. }
    # ]9 Y4 m) c& I3 [
  8. /* USER CODE END 0 */
复制代码
6 T  |4 j. _, L* _9 g

, G# f" ]8 ^' p, D- j0 V

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

  1. /* USER CODE BEGIN 0 */
    0 ?! V) |" c, `  a+ O, y1 Z
  2. void SoftReset(void)) N5 ~  J: [6 I  g' M- a. `, O; K& }
  3. {
      Y% N7 y! H* f% {. L. N
  4.     HAL_NVIC_SystemReset(); // 复位" \/ R0 Z4 E2 Y
  5. }& p) E( P4 e) I
  6. /* USER CODE END 0 */
复制代码
7 K- w# i5 g6 y- |; x

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

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

6 N, Y6 V  H; _; _/ w4 ]& o

转载自: 矜辰所致

如有侵权请联系删除
# q/ }3 v8 K" E8 S, ^2 O
% J; w; Z( `4 l0 O& x2 i- @# t- d1 M
收藏 评论0 发布时间:2023-6-12 19:18

举报

0个回答

所属标签

相似分享

官网相关资源

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