|
有关STM32中HAL_Delay和中断一起使用的问题 昨天笔者使用STM32的外部中断EXTI(HAL库。笔者也是第一次用HAL库)配置一个简单的按键控制,因为需要使用HAL_DELAY进行一个短暂的延时,发现使用过程会造成卡死的现象。我们来分析一下原因: 首先,我在调试的过程中是可以进入主函数的。但是当我调试进入到中断回调函数这块,发现到HAL_Delay这里是无法往下进行的。所以问题就出在这里。
& D. P4 M) N/ n+ X 1-HAL_Delay我们先来看看HAL_Delay代码,先根据这里的代码进行分析 : - 1/**
( {! P0 h: b2 }3 a - 2 * @brief This function provides minimum delay (in milliseconds) based
2 u0 F3 w* i5 `' E* a' f - 3 * on variable incremented.
9 e9 u* C* w) N) q$ |, y* j4 H- Y - 4 * @note In the default implementation , SysTick timer is the source of time base.
; S3 S# \: T/ L" M% h& |- s) o( O, P - 5 * It is used to generate interrupts at regular time intervals where uwTick3 {) D8 j! x. }; @& N6 ^2 ?# g
- 6 * is incremented.
& q- T* W# `" q. T7 S7 B7 [1 i - 7 * @note This function is declared as __weak to be overwritten in case of other% _( g' Y$ u5 s9 v9 g6 x
- 8 * implementations in user file.
$ K( }+ W; [, ?, n& E: R7 o9 z - 9 * @param Delay specifies the delay time length, in milliseconds.* |* v' H5 y% E6 N$ e. p' z
- 10 * @retval None
* j, q6 g& K7 S8 P) }. J8 E, y - 11 */
# I7 q n, V0 e% E' E1 n" u - 12__weak void HAL_Delay(uint32_t Delay)8 `# @3 J6 _1 i6 _8 j( q5 s7 w
- 13{4 r! X1 M: U) Y* z
- 14 uint32_t tickstart = HAL_GetTick();
. S3 f/ S/ Z# y - 15 uint32_t wait = Delay;
1 n) n& A' J9 O+ O& g0 U. S - 16
# `7 C+ u8 i6 }' D0 d& } - 17 /* Add a freq to guarantee minimum wait */* m& c* j A/ h
- 18 if (wait < HAL_MAX_DELAY)+ p: M6 K$ i( K( A$ D2 b1 w
- 19 {
7 z# d4 w u1 r5 T% m# q - 20 wait += (uint32_t)(uwTickFreq);" [- W0 M5 A5 C/ e0 B. v9 k
- 21 }; ?. i8 a0 G9 o4 v- p
- 22
! S6 m( |6 r, O) ~9 w! G' M: l - 23 while ((HAL_GetTick() - tickstart) < wait)
( D1 b0 J# `# d G; @ - 24 {
# p8 i+ X& E3 o; m* V2 j3 M2 `- b - 25 }
. x6 s0 `% F2 R3 j' u- P5 B0 I - 26}
复制代码 4 x. `+ _. r2 J
上面的注释和代码说HAL_Delay计时器的来源是SysTick定时器,并且在固定的时间内产生中断。对于所有的32位单片机来说,有中断肯定是有优先级的。所以这里有基本上有两个原因:一是优先级的问题,我设置的优先级高于HAL_Delay的优先级造成一直在HAL_Delay中卡死,还有一种就是main函数进不去也是一种原因这种原因就是另外一说了。但是我的是可以进入main函数的,所以,只能是中断优先级的问题。所以我查看了systick优先级。
+ n" {/ f' n+ n, ]1 p- A# d M t) m- E; z
) t j, r8 l ]6 g& j9 K' i7 v
% z+ {" h2 x0 g5 f/ i- J- 1/* Tip: To avoid modifying this file each time you need to use different HSE,1 `" b" X. `+ L2 b% R
- 2 === you can define the HSE value in your toolchain compiler preprocessor. */
% y! U' K) o; Z - 3. R( ~2 @' c; K. a3 }' z
- 4/* ########################### System Configuration ######################### */0 f* D% t& `# \7 d
- 5/**
. N- ?) q# f$ @: d( r: x& n. u - 6 * @brief This is the HAL system configuration section: _4 V7 N z. c4 o% S& l" y' l
- 7 */0 B& t5 a T+ l) S7 s' ]1 i2 ?+ k
- 8#define VDD_VALUE 3300U /*!< Value of VDD in mv */8 a) i" b" e5 x8 U. w
- 9#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */& F% }% {' W8 T' K8 m' |
- 10#define USE_RTOS 0U) _; B: l) N) y+ ]: X& `
- 11#define PREFETCH_ENABLE 1U
复制代码 ; A6 a; h2 n" ~ P* z# ~
) B5 N7 P8 Z: @# T3 i* e( h从这句#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */看到,它设置的优先级是最低的。所以是优先级的问题。既然问题找到了现在开始怎样去解决这个问题。
2 f9 K9 b: `! M5 l6 p' ~ 2-问题解决方案1-修改优先级我们可以在代码中或者STM32CubeMX中重新设置systick的优先级。
% u2 n6 n. o" f# ?; B7 t* `; k
1 f, U* A! A9 W
9 S5 L- Q2 [4 t% X: o- o5 M8 N
. e8 ^8 v; l) Z# r
# p* b u6 s9 R- W
2-自己重写延时函数根据____weak void HAL_Delay(uint32_t Delay)这个我们是可以自己重写演示函数的。__weak 的意思就是自己可以实现定义一个同名的函数。 当然如果不想写网上找一个就行。 但是我个人是建议自己重写一个延时函数,这样容易避免后续由HAL_delay引发的其他问题。
" n, M5 i8 O4 d/ T) U7 S; p& J
转载自: 南山府嵌入式 如有侵权请联系删除
7 ^' o) G3 b! K9 p. z; T/ U6 I 0 x: s& L6 S' m) s5 N' p; c
/ ]2 o3 D" u, m8 l$ q4 S$ A, h |