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

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的外部中断是如何使用的。评测内容:' Q: k) @9 @( o, B& _
1、使用外部中断获取按键的状态,并调节LED灯闪烁的频率。' z0 M$ f% X1 c# k5 E* g0 H
所需元件:4 z2 V, a, g- }5 b, s  x+ m
1、STM32L552ZET6Q;7 ~! I" |  w2 }
2、板载红色LED(LD3);
/ Z1 P+ b% M9 V" E5 a3、板载蓝色按键(USER)。0 }+ Y) T* y1 ~! L  n; Y8 @0 T$ K8 _
评测步骤:
+ [! x; o: }1 d% `; A6 F: h1、将按键引脚配置成外部中断模式,打开上回创建的STM32CubeMX工程,将芯片的PC13引脚按照步骤配置成下图所示的设置,第五步为设置程序中的引脚别名,可根据自己的需求进行设置;5 O. v% i( c( g& _& H: B
1-1.png

5 ^; b- o  j& r& s  z2、使能外部中断并设置中断优先级,按照下图所示步骤及内容设置,中断优先级可自己根据需要设置;
: }, F9 k7 w2 z% g. f, v% g
1-2.png
8 L% z- L. A& v2 y& W% x+ U6 M" {$ ~7 \
3、保存工程并生成代码工程。
( K$ _9 I$ n5 {1 V, \5 J4、打开代码工程,发现main.c文件中的GPIO口配置函数多了如下两行设置中山优先级和使能中断的代码;
5 W3 k  r+ _: {
  1. HAL_NVIC_SetPriority(EXTI13_IRQn, 3, 0);
    , l/ F: f1 \+ a( s* Z
  2. HAL_NVIC_EnableIRQ(EXTI13_IRQn);
复制代码
! N( V; L$ Y! k' s( G
5、在stm32l5xx_it.c文件中也多了一段中断服务函数的代码;
$ ?  Z- y+ J+ t% w9 N
  1. void EXTI13_IRQHandler(void)$ ~1 x7 r- l$ c
  2. {, f4 D, G; }1 i, j& @
  3.   /* USER CODE BEGIN EXTI13_IRQn 0 */5 I# p# F" @$ `$ S

  4. - N$ b- b3 L. x! J. K. j
  5.   /* USER CODE END EXTI13_IRQn 0 */5 o7 p8 S1 K; D5 U  X" Y* c
  6.   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);" U' c3 t1 a- N! O; D2 f3 t: ~
  7.   /* USER CODE BEGIN EXTI13_IRQn 1 */
    9 P4 o4 D% V+ D
  8. ' K6 v/ T! m8 C7 z
  9.   /* USER CODE END EXTI13_IRQn 1 */8 ~# T; a4 r3 m3 @3 n/ y
  10. }
复制代码
6、跳转到HAL_GPIO_EXTI_IRQHandler函数的实现,该函数的内容如下;
( c, _& @, N; d! c2 v& b, |
  1. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)8 |6 k2 K9 t. F3 K! n
  2. {. j" V: M+ ]8 W* ?1 ~' O
  3.   /* EXTI line interrupt detected */
    5 D1 E) N9 m/ m, K
  4.   if(__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_Pin) != 0U)7 T) B% O5 N8 r' b, M* j
  5.   {
    : _/ J6 m% j2 @2 G9 }" H
  6.     __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);7 L$ K- |3 k' F+ |( W6 J% d
  7.     HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin);
    3 c+ X; o* J' ^* }4 N6 d3 U
  8.   }
    / K% Y. n; a1 W; |
  9. & Z3 G* Y) ?. g# c! P* w
  10.   if(__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0U)" Y9 q" ]  W' ]
  11.   {2 D* T8 f+ t6 I: E# W8 h1 P
  12.     __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin);
    & N* E1 ^/ X( e3 a; Y9 n( ^! P" \
  13.     HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);
    9 |. B1 f3 C8 W0 c; I& X% ]
  14.   }" }) }7 k$ C6 g! V" b- p9 H
  15. }
复制代码
其中的HAL_GPIO_EXTI_Rising_Callback和HAL_GPIO_EXTI_Falling_Callback函数就是外部中断的回调函数,两个函数内分别有如下注释:1 n# z2 t3 a) z) D$ ?
/* NOTE: This function should not be modified, when the callback is needed,
* i, h, Q5 Z: K           the HAL_GPIO_EXTI_Rising_Callback could be implemented in the user file* R2 {3 ^" M( t; F! k
   */
/* NOTE: This function should not be modified, when the callback is needed,
1 \! _6 k9 @: g/ }; Z6 `( O           the HAL_GPIO_EXTI_Falling_Callback could be implemented in the user file+ g- E- V; U+ ~( g. I" B
   */

8 c% m9 U/ X; ^5 ]5 u意思是这两个函数在用户需要的时候可以在用户文件上实现,实现的内容就是用户需要本次中断执行的内容。
( r" `0 N3 z4 j9 N0 U: S7、回到main.c文件,添加如下函数的实现;
+ b3 L, t5 z( H
  1. void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
    : L# y5 m! W  a- ^2 _4 Z6 M( O/ `
  2. {" f* _9 [/ t) \% ?
  3.   if (GPIO_Pin == USER_BUTTON_Pin)9 {' y7 l' N& e/ U8 a2 e2 u
  4.   {
    3 T( d- U1 ?+ j) [: f
  5.     USER_BUTTON = 1;
    # j6 u; u5 E; @6 K% q
  6.   }+ w6 `( l; |6 M; k+ D) e
  7. }
复制代码
USER_BUTTON为一个全局变量,在文件开头进行定义:_Bool USER_BUTTON = 0;
' v7 g  r9 t/ [7 v* R3 i8、在主函数的循环中添加如下代码;! y1 G9 {: {3 ]/ r/ H7 E) S
一切就绪,重新编译连接并
" i+ W+ I5 a" N! ]( r
  1. /*外部中断操作*/
    1 d! j) t6 L0 Z. d: e2 N+ J
  2. //按键检测程序& {- i6 |$ ^6 `# u. C3 K+ C
  3. if(USER_BUTTON == 1)
    / s0 l/ j/ B/ `: ~9 X, G, |! a
  4. {7 j! b# \/ d7 P4 ^8 d
  5.         u_cycle += 10;
    5 M5 G. E2 M3 o! P- b4 N6 H
  6.         if(u_cycle>=50)8 O5 I6 q% K4 Q- i0 t" w' y
  7.         {4 u  Q  ?$ J! T6 }  j
  8.                 u_cycle = 10;6 E2 g- _9 T% @' d
  9.         }# {! k% `+ N+ U. [# v8 R0 G8 Z
  10.         USER_BUTTON = 0;
    ! N9 j' [, Z4 D" p. c* n
  11. }
    " w% Q' V: Y4 c( E1 q* }9 N
  12. //LED灯闪烁程序/ T$ U+ Z1 y/ J1 z
  13. u_cnt++;* T% {$ H8 S# w& Y2 U2 v# V
  14. if(u_cnt >= u_cycle)
    : J9 Q, ?! b# F1 r6 N
  15. {. V2 z! J% M8 W: o
  16.         u_cnt = 0;- z" b& [' F3 m- `* J% o  k
  17.         LED_R = !LED_R;5 i  V! d* m# B% F; I
  18. }9 b  y. Z. K3 a0 t. I- b  l
  19. HAL_Delay(10);
    9 B. j2 B" p7 n2 X! `" [  U
复制代码

9 p( F, q5 L" w: x下载到开发板上,按下按键观察程序运行情况,还是跟上回的一样,实现了使用外部中断检测按键对LED的闪烁频率进行调节。, l. Q+ {5 ^' b8 `7 ?3 d3 E
总结:' q# `) |0 I7 T- c% b& B0 U
得益于STM32CubeMX的强大功能以及HAL库的完美包装,外部中断的实现似乎并没有那么难(相比于标准固件库来说真的是简单了不少),只需要自己实现一个回调函数就好了,对快速开发是方便了不少。好了,本次评测就到此结束,感谢您的阅读,我们下回再见。3 s4 r0 @1 r2 J! D1 F

, Z) J% x# w  |4 m7 v" ]

) s/ ^/ b3 g0 s9 k3 w
% _* u* T" w( c7 r7 G
3 ~# n% O" A0 h* f

* j0 P7 J1 V1 ~! T( }
收藏 评论0 发布时间:2020-3-21 21:06

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版