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

【经验分享】STM32CubeMX教程及STM32入门(二)外部中断

[复制链接]
STMCU小助手 发布时间:2022-4-26 23:04
简介
1 S2 I! L* _! D9 K; l本次主要讲解STM32的外部中断以及使用STM32CubeMX编写中断程序,实现按键按下点亮LED灯。+ F+ U! z) u3 r4 C! z+ q

" o& J5 Q( Z: d) M. u" jSTM32的中断介绍& a+ c/ P0 R1 {- ?& I
中断是什么

  p8 {8 P, H& d2 f我们可以暂时认为单片机的执行流程是单向的,这件事做完做下一件事。而中断顾名思义,就是当单片机接收到一个信号后,停下手上的程序,转而去执行中断函数里面的程序,执行完再返回原来程序的位置,继续执行未完成的原程序。(就比如你在打单机,结果舍友说等下要上课,你接收到了这个信息,然后只能把游戏存档,先去上课,上完课再继续读档)5 S& a* w! p& {4 o) F

3 S3 a8 m5 B( A6 ?8 m4 VSTM32的中断系统; N6 Y/ X0 B3 N- a
几个概念:中断源,中断通道,中断优先级,NVIC(嵌套向量中断控制器),中断服务程序。4 }! [0 `( M7 U0 V  J

2 V8 f8 X" T3 p  M! ]# y+ j# e中断源:* w7 I0 ~1 v. [% g' i& ~2 w1 P
所谓中断源,就是触发中断的方式。即引起中断的事件或原因,或发出中断申请的来源。分内部和外部中断源。3 K; y' S, ^% y: H7 \
3 K! o9 [# @( q) u
中断通道
' |2 n8 a( A" e) ]* g0 N6 v- OSTM32的中断系统比51单片机强大的多。8051只有两个外部中断的IO口,而STM32的每一个GPIO都能作为外部中断输入。
( A6 h+ `1 U2 v1 _) @STM32的中断控制器支持19个外部中断/事件请求:) V3 R; `: ~) d: \8 M0 d

, n: L" `  Y5 G' }5 X+ p5 O3 E- ~线0~15:对应外部IO口的输入中断。
2 ?- _* G; p4 b线16:连接到PVD输出。
3 T% G7 Z! d, \! z: ?6 W线17:连接到RTC闹钟事件。6 H9 _, M2 F& K! {' M4 G" q
线18:连接到USB唤醒事件。
1 Y: Y- q6 t& s0 {3 L0 g* F/ `( {% n1 Q9 j* C5 u
每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。
: l0 f3 c# J# f$ i
5 |0 A" M2 S: n' c: q从上面可以看出,STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112),* A. U1 Q5 ~+ r+ ^
" x. \. Q4 d2 e4 A) r" w; W( A2 \
STM32F103RCT6(51),那么中断线怎么跟io口对应?
6 W$ a& \+ r0 h+ i- C W9M1{W$Q11[MCFMB0]1.png 7 C5 m: W, m6 {, @% ?3 E$ T
7 `1 B: r8 p$ `
从图上可以看到每组IO的0引脚都对应EXTI0,1引脚对应EXTI1。。。。。以此类推9 _3 N; E$ Z) ?/ _- W4 o

% x8 W# O8 t5 j2 a7 K中断优先级4 x; F* q  O( s- _. ~* a) B! V: l
当出现多个中断的时候,单片机要先执行哪个中断呢?
. K, U8 L; K7 D7 U' t% M为了解决这个问题,单片机设计了中断优先级来安排每个中断的执行先后顺序,也因此产生了中断嵌套。
: |9 [' @, N/ c/ X1 ?32有两个优先级,占先优先级和副优先级。规则如下:* K; J7 C, P! s' i6 [1 v
1.高占先优先级的中断可以打断低占先优先级的中断服务,从而构成中断嵌套。相同占先优先级的中断之间不能构成中断嵌套,只能按先来后到执行。7 ?' |& ~9 v  ?5 W- N  m
2.副优先级不能中断嵌套,但在占先优先级相同的情况下,优先响应副优先级高的中断。
; P) F" `$ Z( S. r( q( ]% G6 M* |" ~* i
NVIC(嵌套向量中断控制器)

" F9 \, m+ E2 I% C' Q; d! \NVIC的作用就是优先级分组(说人话就是,分配有几个占先优先级有几个副优先级)9 s: d1 I' _4 z( c- u' r& \
$ b: d  f  d: P* t& h
c75849746a4349fe93586f06ca2bc85f.jpg ' F+ q$ z  L1 V. G
; P- ^5 p0 ], {. j+ u
STM32以4个比特位表示中断的抢占优先级和响应优先级。中断优先级分组是为了给抢占式优先级和响应优先级在中断优先级寄丛器的四个比特位分配各个优先级数字所占的位数。例如3位用于抢占优先级(优先级有2的三次方等于8种级),1位用于响应优先级(优先级有2的一次方等于2种优先级)。) h: e2 o8 N' ?% B; ?

" g) o, S  k0 ]4 i4 t- H! Z中断服务程序
$ Q/ f3 H  I0 ?+ A& r# G就是一个函数,里面写你要执行的程序。. s& s6 M2 y9 T8 A: Q& D
" z/ `9 u, {" `5 e; i
使用STM32CubeMx编写中断程序的步骤% d+ ~; u1 h! B' T/ l, o) T, |
我们打开上一篇教程的工程,在此基础上增加PA9这个外部中断口。
( S0 ~2 w! ?3 D4 g5 L如图选择IO模式
8 B- t; R5 M2 B3 `% E6 B- F' f+ r, h) N! p; U3 o+ p# b& s
043f121718784e2d9a428ef90e35da38.png
+ k/ ^$ c9 E* G3 o+ X% h4 }+ ^, r9 {! q% A4 W' F
打开NVIC,勾选EXTI line优先级使能
9 Q1 d0 y" A: D# u- o2 y( K4 ^
. c8 z- ^3 A# q) i5 g$ U 285b140726a148fd9dea0dc0b6360722.png # A) G# K; K2 ]9 E# k- \* D
! W3 Q. g# T0 U( j% x
打开GPIO中的NVIC,发现已经配置好了
1 W# G$ B; q' Q/ b0 c! v/ {% K4 G  F- H* o: V
ce37c2a0764543dca219cc2b5ae4e3fa.png
: v' f0 b* P4 N3 ~0 Y$ X& I! y' U  c7 i
接下来配置GPIO的模式,选择下降沿触发,依然是推挽输出7 @5 [7 s0 D$ Q- f' ?. U9 @& i

, |; ~6 |  O( @% v3 C, r9 E0 o# g% m" e
4e4019baf197417ab34e1094ba24e724.png
! ~. |$ J. @0 g5 D. t9 e/ C+ n. A/ m  g: ~' g; d6 j( H
然后生成工程(时钟树之前配置过了). o' g3 L: ~) Z
我们打开工程可以看到在gpio.c文件里面看到,软件已经自动帮我们把IO口配置好了
9 k. k# U0 K1 O4 B. v3 v, R, ?9 ~  Z
9ce1a39ef6714681be77a20a37655fcc.png 7 i- a  ]; B  @+ @+ i4 z

3 d% A6 X+ w$ {2 \stm32f1xx_it.c文件里面的EXTI9_5_IRQHandler函数是PA9的中断服务函数。  e. z  G; b4 r7 Q* R4 n+ W

+ Y* f7 b1 p- l- x4 y" l9 W- h5 s8 q- K, ?7 d* s& S
16d90b83dc4d4a43a855eb77a454f43a.png 7 M3 b( h( T- g* b& J" o9 A

) X) `+ a( G) b: j8 w( g: W8 T- A我们查看HAL_GPIO_EXTI_IRQHandler的定义
, ~1 g4 H) s" R" Q# ?, h4 y
% i* h! M1 O) f+ b! ^0 f! j/ k! Z3 _! K- q/ t$ q  N
]XR4``SHLAH5WFF`Q[V9)]R.png ; C% G' U7 P' v1 i
2 [* H8 }1 e, j  q
0f7de1ddb64a4a68816b9aa45c20556c.png
7 p' `9 U7 o/ I6 y+ a# l$ w! s) [/ s
从他的程序中我们不难看出HAL_GPIO_EXTI_IRQHandler这个函数是用来清除中断标志位的* O4 p! e* k- a: q$ G& E3 g: O* E
在清除之后,还调用了 HAL_GPIO_EXTI_Callback这个函数。
% O8 H' X+ ?3 Z* S$ b) a: |& J0 C9 f* I; m& Z4 p. {
cc1b0b8f8a8746449e299bd6210c95e1.png
- C1 e, F3 m$ m
( w" ]" _1 v* D$ g$ E9 v7 C我们右键跳转到它的定义我们发现,这是一个中断回调函数,而且这个函数里面什么都没有。通过注释的提示我们知道,我们不要在这里就进行修改,而是要在用户文件中重构这个函数。: h) f+ _- W/ I$ I& s6 V
而且有个问题,为什么这个函数前面有一个__weak?
9 W+ `! B5 ~/ q/ _# X1 c; T1 q/ ?(关于__weak修饰符可以看这里链接博文讲的很详细)( d0 N( y6 r7 W0 |4 D$ F
于是我们重新回到main函数,编写了 HAL_GPIO_EXTI_Callback,简单给按键写一下消抖。
5 |6 r3 ]3 B/ B* a& e) m' i5 B8 t$ ~# j5 r* O7 g. V

. n6 Q% ~' {: s/ Q. H" M( w7 z) @ aa7d932163614e3293bcaa4cfc254a34.png
8 r" E& @; @9 |1 R" I$ u# k
" O' f% C: S# C# A2 b3 R( b! Y记得把HAL_GPIO_EXTI_IRQHandler函数里面的中断清除语句注释掉,因为我们写在callback函数里面了。) `- Y3 R6 X; o: F& |
实现按键控制数码管。
: j3 Q3 z  `+ {1 z0 U5 z8 W
3 ~: H' p7 |4 D) e: F7 t, D) O  [" ~' ]9 w- [5 p
  i6 n" _& c) H5 G9 F5 u3 D
赞 收藏 评论0 发布时间:2022-4-26 23:04

举报

0个回答

所属标签

相似技术帖

官网相关资源

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