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

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的外部中断是如何使用的。评测内容:
  M2 Z  r3 V1 p( D2 T+ k! C: h1、使用外部中断获取按键的状态,并调节LED灯闪烁的频率。6 t7 _# ^( `+ F+ j8 @" i
所需元件:0 @" H* i, C# K7 [" D( Y3 ~! X
1、STM32L552ZET6Q;' Q" g! M/ y* o8 z# X/ e; l- W
2、板载红色LED(LD3);
1 D3 f4 W+ Q4 V5 s2 L8 Q3、板载蓝色按键(USER)。
: o0 I( y2 _3 \  D, ?% e7 T: A6 O6 C评测步骤:
  n; q  J0 a2 v1、将按键引脚配置成外部中断模式,打开上回创建的STM32CubeMX工程,将芯片的PC13引脚按照步骤配置成下图所示的设置,第五步为设置程序中的引脚别名,可根据自己的需求进行设置;
% o' l+ ^& `0 d+ p  }
1-1.png

, ]" b" y6 l+ k$ }% |* N8 Q8 w/ ?2、使能外部中断并设置中断优先级,按照下图所示步骤及内容设置,中断优先级可自己根据需要设置;
# w, B0 b: @% S5 J
1-2.png
' c0 Q4 N* V  t. W  @
3、保存工程并生成代码工程。1 w# B5 E$ o: D  M) s* {
4、打开代码工程,发现main.c文件中的GPIO口配置函数多了如下两行设置中山优先级和使能中断的代码;
0 L2 D7 r! a  l5 U
  1. HAL_NVIC_SetPriority(EXTI13_IRQn, 3, 0);, J" ~- [# t/ V& b! G( M" n
  2. HAL_NVIC_EnableIRQ(EXTI13_IRQn);
复制代码
  r5 s3 M# K0 R
5、在stm32l5xx_it.c文件中也多了一段中断服务函数的代码;- t( A- P9 ?8 L% I5 V& X. d" y2 E2 E
  1. void EXTI13_IRQHandler(void)
    : w: o7 v# m8 T/ l) {/ K
  2. {& f# I5 ], ~# l) @
  3.   /* USER CODE BEGIN EXTI13_IRQn 0 */
    8 f9 e% Q' K- [7 L

  4. * d$ v# ^5 E  _5 u! P" u9 Z2 w* N
  5.   /* USER CODE END EXTI13_IRQn 0 */3 B/ A. c+ G% z
  6.   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);$ p8 K' i5 }& T: J( q, X+ g; c7 ^
  7.   /* USER CODE BEGIN EXTI13_IRQn 1 */
    9 H% Z( E- N! \) M: x( V8 K

  8. , \7 B+ G4 F' C
  9.   /* USER CODE END EXTI13_IRQn 1 */
    * d& v0 @+ s! `/ r
  10. }
复制代码
6、跳转到HAL_GPIO_EXTI_IRQHandler函数的实现,该函数的内容如下;
2 Q: ]; c& i, M
  1. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)! F2 o6 j! {* H* K# @& J7 n. @
  2. {. T8 W' x$ v, U4 a. l& ^7 s
  3.   /* EXTI line interrupt detected */0 ^2 |( P$ h6 u! v8 n8 m
  4.   if(__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_Pin) != 0U)$ I  {2 D( `" D  _8 W- J
  5.   {
    ; a5 L& A' m0 y# ?8 J- w( W
  6.     __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);2 y& t1 h  R( v# z* [
  7.     HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin);
    % A" }- f. W! l- v+ k7 ?
  8.   }
    : i6 B1 r; A) _, K/ _
  9. 1 A) s3 S6 z6 k; a9 E
  10.   if(__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0U)/ o( u+ |0 V5 j3 `
  11.   {
    + ]+ |, k2 I7 S4 L
  12.     __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin);8 Q7 Q5 Y( u1 z7 T4 ^! N
  13.     HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);
    # W3 g2 `2 t7 Y# R
  14.   }" x) \% X- z3 V2 K
  15. }
复制代码
其中的HAL_GPIO_EXTI_Rising_Callback和HAL_GPIO_EXTI_Falling_Callback函数就是外部中断的回调函数,两个函数内分别有如下注释:6 f: ~: \# G9 P7 h" F. f- d6 J3 i3 W
/* NOTE: This function should not be modified, when the callback is needed,# Y! n( B/ F: Q/ T- h
           the HAL_GPIO_EXTI_Rising_Callback could be implemented in the user file3 h' j! f) e; ^: I4 t4 u" B. m/ P
   */
/* NOTE: This function should not be modified, when the callback is needed,
3 }" ?9 _7 N/ H' N4 H6 o& @           the HAL_GPIO_EXTI_Falling_Callback could be implemented in the user file
( g& @8 ?3 L3 X. z, ]2 x* _# U( h   */

6 ^2 C& X& x; O' u" B# ^) A' ?4 K+ b7 u意思是这两个函数在用户需要的时候可以在用户文件上实现,实现的内容就是用户需要本次中断执行的内容。  M6 a, s' Y: x
7、回到main.c文件,添加如下函数的实现;  W0 C* i7 _- |! H+ ?2 s/ c2 z  N
  1. void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
    # ~1 p* K. {& V, v  G0 ^- f" u
  2. {9 J/ t& V1 W/ c. G/ @1 r' x7 b8 j
  3.   if (GPIO_Pin == USER_BUTTON_Pin)6 z7 C9 s8 @' f" k: m5 ^
  4.   {
    ! S+ K2 g  U- `* M
  5.     USER_BUTTON = 1;$ T" T$ y* ?9 c: Y* p" Q" G1 u
  6.   }. F- q2 S3 y. c: J, k5 z
  7. }
复制代码
USER_BUTTON为一个全局变量,在文件开头进行定义:_Bool USER_BUTTON = 0;
. V7 S1 g8 A* X: v/ o5 y8、在主函数的循环中添加如下代码;2 m. K2 Y7 Z, j0 i
一切就绪,重新编译连接并6 K$ w0 z# H% Z0 J% V( ~% c5 }, K# n
  1. /*外部中断操作*/& ?5 E( v2 d3 G* B$ [5 K" |, _
  2. //按键检测程序" |4 s( K) E4 T. U' h* _
  3. if(USER_BUTTON == 1); F1 f& e- d& B- h& J& j! e
  4. {
    % y/ ^0 M# {0 C/ G8 I8 P$ U' x
  5.         u_cycle += 10;
    $ D& \8 X* K2 T
  6.         if(u_cycle>=50), K* f7 [! J5 I6 M
  7.         {
    & H, ^& g5 E5 `6 m$ ^3 v
  8.                 u_cycle = 10;) l3 w3 ~0 ~2 P$ K
  9.         }6 `1 ^  x. n1 z) C
  10.         USER_BUTTON = 0;6 ]- U; ^2 p0 |4 d4 ^
  11. }0 h, N1 Y3 l! Q$ c: T
  12. //LED灯闪烁程序
    8 w% Q% L" A2 L$ ]- n
  13. u_cnt++;  C5 \+ ?$ D1 _; {2 z
  14. if(u_cnt >= u_cycle)8 k1 V; p5 k1 B& f+ d6 u
  15. {# k' _" t! J1 l+ Z9 |4 ]
  16.         u_cnt = 0;
    ! ~& ]6 e2 z' _1 q
  17.         LED_R = !LED_R;
    + o4 G, Y# a& g+ |, f" L; t; I
  18. }
    + X: _' Z( F, B4 A/ q( K
  19. HAL_Delay(10);
    % D& i) v/ w# p
复制代码
6 G1 i; j* ^& n5 }6 t4 o/ e% N
下载到开发板上,按下按键观察程序运行情况,还是跟上回的一样,实现了使用外部中断检测按键对LED的闪烁频率进行调节。5 u5 ~+ h7 n6 \
总结:
) D+ k3 J. l2 {& _4 I# k得益于STM32CubeMX的强大功能以及HAL库的完美包装,外部中断的实现似乎并没有那么难(相比于标准固件库来说真的是简单了不少),只需要自己实现一个回调函数就好了,对快速开发是方便了不少。好了,本次评测就到此结束,感谢您的阅读,我们下回再见。
/ H2 N5 v! `  {% {2 a3 H: E& e1 y" z( U: l  {& X! o# m: J/ V
0 ^* b! y4 n6 d% T

, s$ |0 B7 h, g( q2 r
' h; m2 S4 T. R* l. a- ?' Y

# d/ S% l$ @, Y/ v% |0 x, ^
收藏 评论0 发布时间:2020-3-21 21:06

举报

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