|
有关STM32中HAL_Delay和中断一起使用的问题 昨天笔者使用STM32的外部中断EXTI(HAL库。笔者也是第一次用HAL库)配置一个简单的按键控制,因为需要使用HAL_DELAY进行一个短暂的延时,发现使用过程会造成卡死的现象。我们来分析一下原因: 首先,我在调试的过程中是可以进入主函数的。但是当我调试进入到中断回调函数这块,发现到HAL_Delay这里是无法往下进行的。所以问题就出在这里。 8 n" s) ? ]3 b
1-HAL_Delay我们先来看看HAL_Delay代码,先根据这里的代码进行分析 : - 1/** y* D2 T* X' e$ Y1 e1 E
- 2 * @brief This function provides minimum delay (in milliseconds) based- a z" |5 T& ?" U4 p% Z
- 3 * on variable incremented.
+ _( A; I) m3 U' |( e% I* M - 4 * @note In the default implementation , SysTick timer is the source of time base.2 q- x/ K( W5 u& g! I" q$ ^
- 5 * It is used to generate interrupts at regular time intervals where uwTick/ C; U( N2 U. u* h+ n
- 6 * is incremented.
: d- e, u3 ?" B+ t5 \! ]0 u; E - 7 * @note This function is declared as __weak to be overwritten in case of other
2 ^ M+ [+ Z$ m' G) q( I% s* _# \# o - 8 * implementations in user file.
4 A# Y1 Q" T2 L. G& S1 P) Q - 9 * @param Delay specifies the delay time length, in milliseconds.) S9 {; j- b; o: R! B
- 10 * @retval None t4 ~2 |; V/ M% ~
- 11 */4 s2 f+ \; a8 D- j- Q# e. k
- 12__weak void HAL_Delay(uint32_t Delay)
8 C$ x) z. G# x9 F0 ~3 @+ E/ J - 13{$ W+ Y1 d- S3 M+ ?7 j1 x
- 14 uint32_t tickstart = HAL_GetTick();
: o# v# q% W; H' ^- t4 M - 15 uint32_t wait = Delay;
8 G1 r- s3 U9 d( t: a' z - 16
4 { E# u; h7 }0 p e' Y6 e - 17 /* Add a freq to guarantee minimum wait */
4 S% Q, J$ r% q! c& u7 U - 18 if (wait < HAL_MAX_DELAY)& s' A; m, D! @# O
- 19 {1 c/ n: s/ \0 L5 { l
- 20 wait += (uint32_t)(uwTickFreq);
; @4 S5 ~) K! ?/ ]: I - 21 }- X' T- m3 B, Q3 E% {" x2 k$ E
- 22- U) G, s9 u% w
- 23 while ((HAL_GetTick() - tickstart) < wait)
- e7 i: s! P; M% R$ n - 24 {; N0 n) S, Z5 a* W) }5 G. O
- 25 }
2 J) \4 c' w0 d) j9 @" U7 S - 26}
复制代码
# _6 M+ D' F8 c! H' k- ]9 l上面的注释和代码说HAL_Delay计时器的来源是SysTick定时器,并且在固定的时间内产生中断。对于所有的32位单片机来说,有中断肯定是有优先级的。所以这里有基本上有两个原因:一是优先级的问题,我设置的优先级高于HAL_Delay的优先级造成一直在HAL_Delay中卡死,还有一种就是main函数进不去也是一种原因这种原因就是另外一说了。但是我的是可以进入main函数的,所以,只能是中断优先级的问题。所以我查看了systick优先级。
2 O' b" }) @7 d( N" }2 w" K6 }! F7 m( ]1 Z
, I: l$ j5 h* b: k* }9 D
' @ W V: E W) R6 v
- 1/* Tip: To avoid modifying this file each time you need to use different HSE,: m; U0 n+ a: F4 `" z) d
- 2 === you can define the HSE value in your toolchain compiler preprocessor. */
4 w6 k/ K+ ~. [: d* }9 J - 3
4 ~6 o& V7 y$ j( b! V1 [& S1 B - 4/* ########################### System Configuration ######################### */
! \+ s8 Q- W% ?1 K2 C5 N& ]0 A9 z - 5/**
3 i( Q* J: k% `6 I# Z- { - 6 * @brief This is the HAL system configuration section
b& |5 o @2 g4 L$ O8 Y. ^9 y - 7 */
/ I3 Q& p. ]( a8 V& O T - 8#define VDD_VALUE 3300U /*!< Value of VDD in mv */& g9 h9 z+ K# b6 H3 U- `$ s* Z; |
- 9#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */4 L8 u0 Y; S9 w2 v
- 10#define USE_RTOS 0U+ M7 z/ j$ W5 Y+ u, A
- 11#define PREFETCH_ENABLE 1U
复制代码
, C% y* n) U0 k7 L) q
# j. k3 l6 ]. c从这句#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */看到,它设置的优先级是最低的。所以是优先级的问题。既然问题找到了现在开始怎样去解决这个问题。 / d0 {3 e/ c" U6 c
2-问题解决方案1-修改优先级我们可以在代码中或者STM32CubeMX中重新设置systick的优先级。 2 @9 g1 Y/ l% L# }
" s6 c* b# D5 i1 r8 d3 Z
% J% D. ^/ R, R7 K* w9 n n8 g
2 K3 D; D5 o7 G+ s& } y( Y% W6 G( m* L" S- G6 H0 X( X! A
2-自己重写延时函数根据____weak void HAL_Delay(uint32_t Delay)这个我们是可以自己重写演示函数的。__weak 的意思就是自己可以实现定义一个同名的函数。 当然如果不想写网上找一个就行。 但是我个人是建议自己重写一个延时函数,这样容易避免后续由HAL_delay引发的其他问题。
' h8 m* {: ~3 V8 w# z$ t
转载自: 南山府嵌入式 如有侵权请联系删除
W% g) q0 f1 o7 V% `
9 Q2 ~4 C* B/ ~' ?5 s3 S7 A8 p% d- c& l* ]
|