|
有关STM32中HAL_Delay和中断一起使用的问题 昨天笔者使用STM32的外部中断EXTI(HAL库。笔者也是第一次用HAL库)配置一个简单的按键控制,因为需要使用HAL_DELAY进行一个短暂的延时,发现使用过程会造成卡死的现象。我们来分析一下原因: 首先,我在调试的过程中是可以进入主函数的。但是当我调试进入到中断回调函数这块,发现到HAL_Delay这里是无法往下进行的。所以问题就出在这里。 3 [' b5 X* [2 s( U
1-HAL_Delay我们先来看看HAL_Delay代码,先根据这里的代码进行分析 : - 1/**5 g& Z; i6 i+ \# j4 k7 r5 {! w- s
- 2 * @brief This function provides minimum delay (in milliseconds) based
2 n& J# @( w6 I. g$ `% g - 3 * on variable incremented.7 M o* M- S( {7 B
- 4 * @note In the default implementation , SysTick timer is the source of time base.8 v9 |% f9 ^+ F3 p( l
- 5 * It is used to generate interrupts at regular time intervals where uwTick: B$ ~7 ~4 o- r" i
- 6 * is incremented.
3 R$ d8 T6 T% E$ k6 D# h - 7 * @note This function is declared as __weak to be overwritten in case of other2 y+ j* w: Z; h" F) G( }/ A
- 8 * implementations in user file.
8 G3 g# Y# v! P6 N2 Y7 G - 9 * @param Delay specifies the delay time length, in milliseconds.2 }0 Z+ G$ }! a1 |- C1 G w: ]* R( h, `
- 10 * @retval None
! V+ S3 R7 Y7 f' | - 11 */
+ _5 ?8 m2 S+ S9 @! y2 j - 12__weak void HAL_Delay(uint32_t Delay)/ c/ l y" E# C, ` O
- 13{6 j, u+ l6 a6 G8 q
- 14 uint32_t tickstart = HAL_GetTick();- r2 b. }& v* O8 E1 D
- 15 uint32_t wait = Delay;$ j1 d; I; D+ v& O* u1 \
- 16
) R" j/ z1 y* q' n' g - 17 /* Add a freq to guarantee minimum wait */
0 y3 P# o& S. y - 18 if (wait < HAL_MAX_DELAY)
8 k8 B |0 g; A, _9 }6 ` - 19 {* Q2 y% Y) [1 o5 d
- 20 wait += (uint32_t)(uwTickFreq);' }* W$ [4 J) e5 M0 \$ J
- 21 }( D2 M2 o/ P& t4 l7 N* t
- 22
) D. M$ K- ~# W, p( @- r8 A1 v& m - 23 while ((HAL_GetTick() - tickstart) < wait)
; Q. f: x* \, A( ? - 24 {- O! _ F6 h! s: o1 T
- 25 }
! [2 t: ]$ H& X1 f0 H0 E+ U - 26}
复制代码 2 d7 P: E; l8 g
上面的注释和代码说HAL_Delay计时器的来源是SysTick定时器,并且在固定的时间内产生中断。对于所有的32位单片机来说,有中断肯定是有优先级的。所以这里有基本上有两个原因:一是优先级的问题,我设置的优先级高于HAL_Delay的优先级造成一直在HAL_Delay中卡死,还有一种就是main函数进不去也是一种原因这种原因就是另外一说了。但是我的是可以进入main函数的,所以,只能是中断优先级的问题。所以我查看了systick优先级。 a- Q6 B; @3 L/ d4 h8 @
4 d3 [, D) A& U- P! }" F
( Z! l8 y8 O% j# N4 Q! L4 U" P: ^, k- Q( T! o
- 1/* Tip: To avoid modifying this file each time you need to use different HSE,
, u! D/ K9 d" J. R M - 2 === you can define the HSE value in your toolchain compiler preprocessor. */
8 n8 X- ~# @- E0 h - 3( K# z$ M" d \8 S% N
- 4/* ########################### System Configuration ######################### */9 ~% n4 d( p1 D' X* o
- 5/**: V! f% V' h$ i
- 6 * @brief This is the HAL system configuration section
- A0 D9 H0 f$ f& \3 d# }3 r5 K% V - 7 */. P/ c+ \, N- Q; b# D3 }) o5 F# P
- 8#define VDD_VALUE 3300U /*!< Value of VDD in mv */
* D S' R- x" h# y" h* ] - 9#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */
- G5 V# L. V6 |3 t/ _7 ` - 10#define USE_RTOS 0U
( C: {0 \; b* B4 v! E4 q - 11#define PREFETCH_ENABLE 1U
复制代码
+ |1 M: F/ ^5 T% n0 ]/ k
* |+ r' A+ h$ t% i7 `从这句#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */看到,它设置的优先级是最低的。所以是优先级的问题。既然问题找到了现在开始怎样去解决这个问题。
; Z9 t2 F& L7 r% D- g 2-问题解决方案1-修改优先级我们可以在代码中或者STM32CubeMX中重新设置systick的优先级。 6 t; \5 ~% R$ ? p
' e( S2 V0 i* Z3 }, ]& C. f
4 D2 W0 ^$ a- }' a% z, d, |
7 i" s3 Z( m. L( J V- n+ D, _$ x4 h2 C1 @9 @8 n
2-自己重写延时函数根据____weak void HAL_Delay(uint32_t Delay)这个我们是可以自己重写演示函数的。__weak 的意思就是自己可以实现定义一个同名的函数。 当然如果不想写网上找一个就行。 但是我个人是建议自己重写一个延时函数,这样容易避免后续由HAL_delay引发的其他问题。 ' C) H- Z& D, H( o* A- r9 j
转载自: 南山府嵌入式 ( y4 g, ?/ k4 Z @( n# B
% o+ z5 Z, {/ n; D7 Z" f4 j& I |