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

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的外部中断是如何使用的。评测内容:
3 W! Y4 g3 b% P9 a8 E1 {3 V0 z& @1、使用外部中断获取按键的状态,并调节LED灯闪烁的频率。
8 z$ G6 o1 p7 n; @* e2 Y* k所需元件:
5 s# S$ `3 \5 u0 B; T$ U1、STM32L552ZET6Q;
3 k, }' o1 {- t2、板载红色LED(LD3);( ~- E( Z6 a4 j' x% I
3、板载蓝色按键(USER)。
  Q' N* I6 H1 m2 \: f; P评测步骤:
% z5 s" Y9 F0 E6 O# {4 |( s; C1、将按键引脚配置成外部中断模式,打开上回创建的STM32CubeMX工程,将芯片的PC13引脚按照步骤配置成下图所示的设置,第五步为设置程序中的引脚别名,可根据自己的需求进行设置;
6 P$ ]9 ~6 ~: j/ t' u
1-1.png

* v" |, Z" L' d4 r2、使能外部中断并设置中断优先级,按照下图所示步骤及内容设置,中断优先级可自己根据需要设置;
# ^1 \6 ^7 u1 {6 M  Z
1-2.png

8 ?# o- @8 J9 x% I5 g- z5 ~9 v3、保存工程并生成代码工程。+ N' x! y8 ]8 m  j  V5 P  |% @. P
4、打开代码工程,发现main.c文件中的GPIO口配置函数多了如下两行设置中山优先级和使能中断的代码;
; R5 L4 g- {( g9 V# n8 u# G8 ~3 ]
  1. HAL_NVIC_SetPriority(EXTI13_IRQn, 3, 0);
    $ t7 @" N1 c4 f* N& U  }! p+ N
  2. HAL_NVIC_EnableIRQ(EXTI13_IRQn);
复制代码

1 w8 y( [  D/ F$ s5、在stm32l5xx_it.c文件中也多了一段中断服务函数的代码;. ?* Y3 ~5 l- }4 e' f
  1. void EXTI13_IRQHandler(void)
    1 L2 H: p, N# x; d8 p' b! N0 V
  2. {1 D$ {0 I/ e- ]7 N( l
  3.   /* USER CODE BEGIN EXTI13_IRQn 0 */
    $ J! X4 y- D. |* _" {# |6 B
  4.   s; B+ r1 d  J$ G" |" B
  5.   /* USER CODE END EXTI13_IRQn 0 */
    8 r2 ]+ G% [5 F3 v2 h: }
  6.   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);, A& E, I" {9 T# C( u
  7.   /* USER CODE BEGIN EXTI13_IRQn 1 */
    : i) L$ r( R7 ?& q- W7 I3 W3 |8 G5 Y
  8. 6 A5 B9 @0 c* i: b( u* q
  9.   /* USER CODE END EXTI13_IRQn 1 */
    7 x. n7 h4 h% Y6 _" e
  10. }
复制代码
6、跳转到HAL_GPIO_EXTI_IRQHandler函数的实现,该函数的内容如下;5 U) `* t+ V+ ?/ M/ t! s7 e
  1. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)) z  \3 n1 P- `+ `# D( Y
  2. {
    3 P% z% d8 L$ I1 X
  3.   /* EXTI line interrupt detected */: l8 q) X5 X, l& b
  4.   if(__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_Pin) != 0U)  M* x/ K: G% G' G. P: l" G& n
  5.   {
    3 n; j+ Z: q$ p' P& T) ^7 l
  6.     __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);) G; {  O+ F) _5 }
  7.     HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin);
    $ `4 }4 E1 s8 O8 q
  8.   }9 G2 `& C. N! o) k7 ^8 v4 }" Q/ A

  9. 9 L3 x4 J3 n3 v& [
  10.   if(__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0U)
    2 D. x- ^* U$ R% s# b
  11.   {
    ) c& W" ~& f+ N$ K- Z8 t. ^
  12.     __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin);
    ' Z: n) J- }! F" b( }3 i9 D  N9 P
  13.     HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);
    6 o4 M( \4 j1 G( m) b
  14.   }! x8 r  K% T- {, e, ?
  15. }
复制代码
其中的HAL_GPIO_EXTI_Rising_Callback和HAL_GPIO_EXTI_Falling_Callback函数就是外部中断的回调函数,两个函数内分别有如下注释:
: g7 D1 J& U) x  f2 \
/* NOTE: This function should not be modified, when the callback is needed,
( {6 M. q, O/ M( w" C" B           the HAL_GPIO_EXTI_Rising_Callback could be implemented in the user file' }: S( ?! q; j, ~
   */
/* NOTE: This function should not be modified, when the callback is needed,+ J6 k6 z) Z2 w+ |$ X  f
           the HAL_GPIO_EXTI_Falling_Callback could be implemented in the user file: }6 |! D! u2 `! B, }2 @
   */

* q' g6 d+ V* z( @# X: G! Z, u意思是这两个函数在用户需要的时候可以在用户文件上实现,实现的内容就是用户需要本次中断执行的内容。- S: J+ k6 |9 m3 I/ O
7、回到main.c文件,添加如下函数的实现;- B4 A6 e# c- q: u3 }0 d8 A
  1. void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
    8 W6 E8 H, x. ^! I% |; w
  2. {/ W6 [3 H) j/ q
  3.   if (GPIO_Pin == USER_BUTTON_Pin): d6 b- D+ z' k# |
  4.   {2 q& w1 {4 e" s, a$ {+ X
  5.     USER_BUTTON = 1;! S0 s4 r& T- b; E8 e5 q; v
  6.   }
    1 l$ A7 ]* ?9 r
  7. }
复制代码
USER_BUTTON为一个全局变量,在文件开头进行定义:_Bool USER_BUTTON = 0;
/ o  l( `0 r2 r! p8、在主函数的循环中添加如下代码;
- x' X4 g, i" }; R# a一切就绪,重新编译连接并4 w' F8 i* ]8 G1 S$ |$ g( E7 f
  1. /*外部中断操作*/
    * r$ X: K$ `) U$ Y- _' i4 I
  2. //按键检测程序
    - s( X6 t+ n3 r, |
  3. if(USER_BUTTON == 1)
    3 @; R+ ^6 T, k; N) E  n
  4. {
    4 ~. l' f8 |8 D" |( e
  5.         u_cycle += 10;( U( Z. y* @  o1 T! D3 {5 {
  6.         if(u_cycle>=50)  w6 z0 x7 j6 Y" k0 v
  7.         {  [4 u  H7 s! |
  8.                 u_cycle = 10;
    0 g, \$ n: ^. S; G
  9.         }
    , K3 X8 W- z+ ?( Y2 b5 s/ V
  10.         USER_BUTTON = 0;
    , ^, P5 g3 J1 Y7 K: @: X3 y
  11. }
    : c2 {+ W" _: y* Z3 q
  12. //LED灯闪烁程序! l3 e9 O, S- Y9 Q) |9 i
  13. u_cnt++;6 {1 ?/ ?, R" H
  14. if(u_cnt >= u_cycle)$ ~* b3 t. q9 n# d" h$ Z1 o
  15. {
    , C3 {6 c& }  ^+ W* k' `
  16.         u_cnt = 0;
    ! m9 O% }' [( P
  17.         LED_R = !LED_R;* w: T* v; S. e  \& N. B
  18. }
    % F3 ^/ P; A, f' ~9 F% \
  19. HAL_Delay(10);% A7 x9 e( o7 O6 Z5 E
复制代码
8 Q  i7 c$ c7 h
下载到开发板上,按下按键观察程序运行情况,还是跟上回的一样,实现了使用外部中断检测按键对LED的闪烁频率进行调节。
6 C1 I6 D9 r. @' g. \" j总结:! c1 P. P* B/ e+ n- F# Z$ I7 |/ z; r
得益于STM32CubeMX的强大功能以及HAL库的完美包装,外部中断的实现似乎并没有那么难(相比于标准固件库来说真的是简单了不少),只需要自己实现一个回调函数就好了,对快速开发是方便了不少。好了,本次评测就到此结束,感谢您的阅读,我们下回再见。
( ]1 }3 Y) V/ k7 }! u; S+ j: K7 ~/ V" t; Z' _! G
/ O& X! Y  e) V

7 i* ^) ~8 w: N
+ ^' M5 v( x- m6 U

6 G% _3 a4 _5 @9 c/ {* W3 v
赞 收藏 评论0 发布时间:2020-3-21 21:06

举报

0个回答

所属标签

相似技术帖

官网相关资源

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