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

基于STM32中HAL_Delay和中断一起使用经验分享

[复制链接]
攻城狮Melo 发布时间:2023-6-14 14:57
有关STM32中HAL_Delay和中断一起使用的问题
昨天笔者使用STM32的外部中断EXTI(HAL库。笔者也是第一次用HAL库)配置一个简单的按键控制,因为需要使用HAL_DELAY进行一个短暂的延时,发现使用过程会造成卡死的现象。我们来分析一下原因:
首先,我在调试的过程中是可以进入主函数的。但是当我调试进入到中断回调函数这块,发现到HAL_Delay这里是无法往下进行的。所以问题就出在这里。

  `, n& O: @7 @( |! H* K
1-HAL_Delay
我们先来看看HAL_Delay代码,先根据这里的代码进行分析 :
  1. 1/**  A0 @. }* l- u
  2. 2  * @brief This function provides minimum delay (in milliseconds) based# y+ r5 K& {: ?: U
  3. 3  *        on variable incremented.. F* [, B' W. l% y
  4. 4  * @note In the default implementation , SysTick timer is the source of time base.' M. n1 y3 f$ V3 `
  5. 5  *       It is used to generate interrupts at regular time intervals where uwTick3 D7 P8 ^* K$ H0 X
  6. 6  *       is incremented.1 ^9 c7 S! X: U; |
  7. 7  * @note This function is declared as __weak to be overwritten in case of other3 e2 T: |! A0 }0 `7 u8 N
  8. 8  *       implementations in user file.
    7 ]4 p8 V1 [3 h2 [( n$ A
  9. 9  * @param Delay specifies the delay time length, in milliseconds.) M$ h" V. I+ H, F, v0 G2 G
  10. 10  * @retval None
    . r$ J9 v/ Y8 O) J- K
  11. 11  */
    : [! q, J' {# D% G. D* K
  12. 12__weak void HAL_Delay(uint32_t Delay)* `( G3 Q" J7 r2 U
  13. 13{
    ( J( C4 u& n& ]
  14. 14  uint32_t tickstart = HAL_GetTick();2 O1 w4 r1 k% e  ?* o1 C& T
  15. 15  uint32_t wait = Delay;7 A! r4 H& Y) A( |5 F* \
  16. 16
    ' v- P0 \' \/ @6 N4 L4 @, N
  17. 17  /* Add a freq to guarantee minimum wait */& y3 S3 \1 S8 n
  18. 18  if (wait < HAL_MAX_DELAY)
    1 e- O) {; p. ~
  19. 19  {& {1 T; i5 F! n
  20. 20    wait += (uint32_t)(uwTickFreq);+ k& o. I2 `2 m9 h# i% @1 l, t7 g
  21. 21  }
    7 `* Y7 |. s, `; `( I. \$ j# v
  22. 22+ k9 ^3 K0 Y3 V! Y0 b7 @. j: S
  23. 23  while ((HAL_GetTick() - tickstart) < wait)) s7 I9 [, b* m
  24. 24  {
    2 t5 b4 N7 p! X# w' D
  25. 25  }! s8 [# j, y3 I! u# @% ~" {2 J
  26. 26}
复制代码
6 B  G; V$ T# X% Z5 k) ~/ T4 @
上面的注释和代码说HAL_Delay计时器的来源是SysTick定时器,并且在固定的时间内产生中断。对于所有的32位单片机来说,有中断肯定是有优先级的。所以这里有基本上有两个原因:一是优先级的问题,我设置的优先级高于HAL_Delay的优先级造成一直在HAL_Delay中卡死,还有一种就是main函数进不去也是一种原因这种原因就是另外一说了。但是我的是可以进入main函数的,所以,只能是中断优先级的问题。所以我查看了systick优先级。

- t! M! ~+ [/ l8 A7 E
( N) @. t; n0 c  V. u2 ^+ C
微信图片_20230614145722.png
, I4 d- {- Q  a! u2 n* ?& q7 [* C1 d+ ]9 i# @( g$ A! i5 p
  1. 1/* Tip: To avoid modifying this file each time you need to use different HSE,8 o$ @: j: n6 c9 r0 g( s2 [" {. q
  2. 2   ===  you can define the HSE value in your toolchain compiler preprocessor. */
    ' r4 A" X/ A3 x$ t
  3. 3
    ! Y! R& n/ ?% D9 Y
  4. 4/* ########################### System Configuration ######################### */( ?8 ]$ `( r. W
  5. 5/**5 U1 o. d" i  ?$ V
  6. 6  * @brief This is the HAL system configuration section2 n) O! ]) j( i
  7. 7  */1 e  t1 f6 R/ {4 D
  8. 8#define  VDD_VALUE                    3300U /*!< Value of VDD in mv */
    ; p( i7 ], V' A
  9. 9#define  TICK_INT_PRIORITY            0x0FU /*!< tick interrupt priority */* p' R, j  u$ K& D) c0 H# \
  10. 10#define  USE_RTOS                     0U! v" O; i$ _# z
  11. 11#define  PREFETCH_ENABLE              1U
复制代码

- t! _+ K- T# L5 E6 T/ Z4 C* L3 v+ E6 e$ U9 O8 W+ B, R
从这句#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */看到,它设置的优先级是最低的。所以是优先级的问题。既然问题找到了现在开始怎样去解决这个问题。

2 u& }" p- i/ x4 i7 z: Z2 ^5 z3 G
2-问题解决方案1-修改优先级
我们可以在代码中或者STM32CubeMX中重新设置systick的优先级。
( w8 ]4 q& h; k
; o) E" ^7 x/ ?
微信图片_20230614145718.png ! [' m# ^% X3 y
) u9 b- {! X8 A0 d' E+ q
1 d. M  q8 O- ]
2-自己重写延时函数
根据____weak void HAL_Delay(uint32_t Delay)这个我们是可以自己重写演示函数的。__weak 的意思就是自己可以实现定义一个同名的函数。
当然如果不想写网上找一个就行。
但是我个人是建议自己重写一个延时函数,这样容易避免后续由HAL_delay引发的其他问题。

, @. [3 \% _2 [
转载自: 南山府嵌入式
如有侵权请联系删除
/ Y6 M0 T1 j8 ~/ B1 z: D

/ G* W1 Z( i, I% M
) ]( Y% d" U/ p  D2 {+ _, ^
收藏 评论0 发布时间:2023-6-14 14:57

举报

0个回答

所属标签

相似技术帖

官网相关资源

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