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

NUCLEO_L552ZE_Q 『人生中的首块STM32L552开发板』┅ 外部中断

[复制链接]
三界狗 发布时间:2020-3-21 21:06
上回向大家介绍了如何使用GPIO口的输出功能点亮一盏LED灯,以及使用GPIO口的输入功能读取按键的状态控制LED的闪烁频率,然鹅,获取按键的状态采用的是主循环查询的方法,这有一个弊端,试想当主循环的循环周期非常长的时候,比如夸张点说要1秒,那就得一直按着按键等到程序扫描到按键的输入引脚后才能放开,这个等待时间最长需要1秒,这是很糟糕的,我可没有这个耐心去等,比如在将一个数从1调节到100的时候,那后果是可想而知的。为此,就有必要引入一个叫中断的神奇东西,程序中的中断,会把正在运行的普通程序或者低级的中断服务程序打断,先运行本中断服务函数内的程序,就好比我们日常生活中的突发事件,你正在洗衣服,突然快递小哥到你家门口了,你得放下手上的衣服先去取个快递,总不能让快递小哥在门口等你把衣服洗完吧。中断还有很多种分类,在普通的51单片机中有三类中断共五个中断源,分别是外部中断0和1、定时器中断0和1以及串口中断,而在STM32中的中断那可多了去了,比方说有GPIO外部中断、定时器中断、串口中断、DMA中断、ADC中断等等等等,每个中断都有它独特的功能,而本次我们需要的就是这当中的GPIO外部中断,好了,废话不多说,接下来我们就来研究研究STM32L552的外部中断是如何使用的。评测内容:, n; S( F  w- u
1、使用外部中断获取按键的状态,并调节LED灯闪烁的频率。
! q( V% H) O0 ~/ R( ]所需元件:
' M7 M: C; A5 E( t4 [/ Q/ c" [7 g1、STM32L552ZET6Q;! W8 t- h  A2 p; V& |  ?% ^
2、板载红色LED(LD3);) C& n; M; L$ j
3、板载蓝色按键(USER)。3 g( O; X8 w/ H0 F! z
评测步骤:
4 c" d6 K( ^. D$ U; Z1、将按键引脚配置成外部中断模式,打开上回创建的STM32CubeMX工程,将芯片的PC13引脚按照步骤配置成下图所示的设置,第五步为设置程序中的引脚别名,可根据自己的需求进行设置;/ Q- u' Y- o5 }9 n0 A
1-1.png

, }. R" l% H: G2、使能外部中断并设置中断优先级,按照下图所示步骤及内容设置,中断优先级可自己根据需要设置;
# z: s: F9 S$ D" U8 r% K6 A
1-2.png

: B4 H' i) c2 Y% B# ^3、保存工程并生成代码工程。* c( C! u7 M; n' L
4、打开代码工程,发现main.c文件中的GPIO口配置函数多了如下两行设置中山优先级和使能中断的代码;) `$ G! n% ]* A- v/ o5 Q8 T
  1. HAL_NVIC_SetPriority(EXTI13_IRQn, 3, 0);& `7 z9 k( {: G/ {$ O. G- [# M
  2. HAL_NVIC_EnableIRQ(EXTI13_IRQn);
复制代码

, b( A8 y& W4 ~" {. |# n5、在stm32l5xx_it.c文件中也多了一段中断服务函数的代码;2 P2 ?0 I# ?6 h+ t- c
  1. void EXTI13_IRQHandler(void)
    7 J4 Y% y5 L. S" M4 K+ K
  2. {
    $ |9 u: c1 ~; M) H5 C- N; b
  3.   /* USER CODE BEGIN EXTI13_IRQn 0 */) \, S0 l7 \* h1 Q- [" n
  4. 9 b: f8 `' }6 K. r- r8 Y
  5.   /* USER CODE END EXTI13_IRQn 0 */
    5 F% L) Y, E; c% ]- Z8 d3 ?* f' E" y
  6.   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);, n: ]. d* B6 R: S% ?; N5 r! v% u
  7.   /* USER CODE BEGIN EXTI13_IRQn 1 */
    6 g) t* q; J. Y, K) S& X
  8. 7 S9 Y  D9 O' X; ]: X% n' T& D4 c
  9.   /* USER CODE END EXTI13_IRQn 1 */
    ! s; H& v- W3 g; M, q0 h' q/ k
  10. }
复制代码
6、跳转到HAL_GPIO_EXTI_IRQHandler函数的实现,该函数的内容如下;
4 g6 I7 d% F# e/ D
  1. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)9 L) n4 z; V# i4 J+ R  Q9 ^+ u: |+ C
  2. {
    ' M. d4 Y- W' N: V, b; m
  3.   /* EXTI line interrupt detected */
    $ F2 N- _! T# S* g
  4.   if(__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_Pin) != 0U)
      d3 q3 H9 r% \3 T, ]
  5.   {
    8 F9 }1 ^0 s$ I( F5 d$ b. F6 z
  6.     __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);0 G2 ]; r, D  K% Z6 d: O+ W
  7.     HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin);
    4 `! G2 A% u1 M* D! H# H
  8.   }
    ) K+ j" {4 ~7 K( v/ {- a

  9. 2 T! s. U! v, j: \
  10.   if(__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0U)
    + f7 h( S" C! q. h/ D& h7 b6 y
  11.   {4 ?6 E7 ^: d) A0 @3 \/ B
  12.     __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin);& u3 Z3 ?% R" g- H7 i" A& d% L  ?
  13.     HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);2 w. ~8 \( U! a! D  r: @( ^
  14.   }) B  k" q9 a1 b0 u, E3 P# Y+ U/ Y! @: g
  15. }
复制代码
其中的HAL_GPIO_EXTI_Rising_Callback和HAL_GPIO_EXTI_Falling_Callback函数就是外部中断的回调函数,两个函数内分别有如下注释:
5 W) {& E9 t3 b! G) x0 x/ B+ f1 X
/* NOTE: This function should not be modified, when the callback is needed,  }) F; h% C' ?' o* y6 n& g' _2 ]' {
           the HAL_GPIO_EXTI_Rising_Callback could be implemented in the user file
# b1 R& E5 i$ l1 x% z$ e: d   */
/* NOTE: This function should not be modified, when the callback is needed,& I. }1 I% _$ E% c
           the HAL_GPIO_EXTI_Falling_Callback could be implemented in the user file( \" K/ w8 ?7 N* y
   */

. r0 [# R0 u( E2 v意思是这两个函数在用户需要的时候可以在用户文件上实现,实现的内容就是用户需要本次中断执行的内容。/ p  v: n' c( u  e+ p: o5 o/ P
7、回到main.c文件,添加如下函数的实现;9 y5 Z4 W5 F: D- T
  1. void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)" h  g- S  V9 T3 r9 f% V8 _8 N
  2. {
    $ _2 t3 ~  S4 r9 {  J
  3.   if (GPIO_Pin == USER_BUTTON_Pin)
    - b: m5 h2 a3 y! a+ b- W
  4.   {
    6 Z) s+ c2 V  \" p  b( ?) h
  5.     USER_BUTTON = 1;3 M  P6 \5 e$ _* `
  6.   }
      w4 j( T2 z$ P5 I5 r
  7. }
复制代码
USER_BUTTON为一个全局变量,在文件开头进行定义:_Bool USER_BUTTON = 0;5 c( R' p" B6 t% q6 W. N  |
8、在主函数的循环中添加如下代码;! S% o% h0 z1 f+ p! c* e3 ^4 P4 Q
一切就绪,重新编译连接并
, y& }8 [% `" C" b
  1. /*外部中断操作*/2 |5 p1 ^: A$ d: X9 C* J; S6 h
  2. //按键检测程序  g8 f/ {3 f; @2 [, I
  3. if(USER_BUTTON == 1)
    . A6 Z/ }7 q$ d9 \1 L
  4. {
    + j8 F, E! d( M& f# g8 l# P
  5.         u_cycle += 10;3 {" P+ b' w# m$ q* m
  6.         if(u_cycle>=50)
    9 P# f) _5 \  j9 U* m
  7.         {
    1 R0 J9 {! x5 s' g! N' H" ]' r, a
  8.                 u_cycle = 10;
    - p/ I4 U! {* U( r( s
  9.         }
    , I+ i. A& ^. n0 d8 C" i* T
  10.         USER_BUTTON = 0;( t6 j# V# S) Y6 t1 W  n2 v- E7 F
  11. }
    & v$ o! n% o  ?6 @, d0 A: \: Q
  12. //LED灯闪烁程序- B" E: W0 ^# B0 Q" q+ e. N
  13. u_cnt++;
    6 X  [7 v8 ?, S+ {% A3 H; e
  14. if(u_cnt >= u_cycle)0 |: a5 N; C* V. M) P( k3 i
  15. {/ `! a+ v# W7 o* r4 c
  16.         u_cnt = 0;
      A6 a" q5 v0 S- i) t) G
  17.         LED_R = !LED_R;2 d  E: D. N$ k0 \' a: m
  18. }
    # W1 F2 C+ a4 j3 Z- S4 x1 A
  19. HAL_Delay(10);
    " W+ C! z" s0 r6 L
复制代码

) Y: A' h, b' Y& e  i下载到开发板上,按下按键观察程序运行情况,还是跟上回的一样,实现了使用外部中断检测按键对LED的闪烁频率进行调节。
9 R' x! H' x0 I3 d总结:/ C! F5 @& F7 n/ K& R7 Q( P
得益于STM32CubeMX的强大功能以及HAL库的完美包装,外部中断的实现似乎并没有那么难(相比于标准固件库来说真的是简单了不少),只需要自己实现一个回调函数就好了,对快速开发是方便了不少。好了,本次评测就到此结束,感谢您的阅读,我们下回再见。
. u& r0 O. F. U; b0 W) a; ~' V1 h
( E2 t- W6 S# ~/ q) h
& m6 T. ?6 F3 k
( ]* w' k6 w0 o

2 b2 B, i4 i& K& g) A
收藏 评论0 发布时间:2020-3-21 21:06

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版