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

stm32——STM32 中断

[复制链接]
feixiang20 发布时间:2018-1-16 18:25
本帖最后由 feixiang20 于 2018-1-16 20:33 编辑 4 ]! J9 d; V" G- M: Z
! L" t: R1 ]+ ]
这次实验,我们将学习如何使用 STM32 的外部输入中断。在前几次的学习中,我们掌握了 STM32 的 IO 口最基本的操作。 本次实验我们将介绍如何将STM32 的 IO 口作为外部中断输入,在本实验中,我们将以中断的方式,实现按键控制 LED 亮灭的功能 。 实验目标:! I# u2 e% I) V" u6 @, e" T' m7 R
1、 了解 STM32 的中断模式 NVIC 。7 i0 ?# w+ o; W, X; p0 L5 b  \4 y
2、 了解外部中断的使用方式 。) i. M- ?: O/ g* u9 m
8 {' z" W8 Z3 m+ ~# C' s
中断的概念
# r0 t( f) Y* y: W  S6 h如果学员有单片机的基础,那么就会知道中断的概念。所谓中断是指 CPU 在执行当前程序的过程中,由于某种随机出现的外设请求或 CPU 内部的异常事件,使 CPU 暂停正在执行的程序而转去 执行相应的服务处理程序;当服务处理 程序运行完毕后,CPU 再返回到暂停处继续执行原来的程序。 而有些中断还能够被其他高优先级的中断所中断,那么这种情况又叫做中断的嵌套。
7 |* s5 v, m5 ]( \0 O, ~! `; d/ M
STM32  的中断1) STM32  中断分组* j+ b% Z* G! l2 w  V) b/ K( \
STM32 的中断一共有 68 个可屏蔽中断通道16 个可编程的优先等级;什么叫做可编程等级呢? 首先我们来看一下STM32 中断等级式,STM32 使用一个 4 位寄存器 来设置中断等级的,4 位长度可以设置 16 个优先等级(2 的 4 次方等于 16); 而这个优先等级是可以设置的,所以叫做可编程等级。而且呢,这个 4 位长 度的优先等级还可以分为两部分,一部分叫做抢占优先级,一部分叫做响应 优先(些资料也叫做亚优先级) (比如说: 4 位里面设置 1 位抢占优先级,3 位的响应优先级。)在这里大家可能有点糊涂了,分成抢占优先级和响应优先级又是什么用呢?
  f8 f& J/ n; h5 j( D7 X0 P在 STM32 的 NVIC 中规定: 抢占优先级高的可以中断抢占优先级比它低 的中断函数,不过相同抢占优先级的之间是不能相互中断的。响应优先级 之间是不能相互中断的,有人或许既然都不能中断了,那响应优先级还有什 么意义呢?如果这两个中断同时到达,则中断控制根据他们的响应优先级 高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等, 则根据他们在中断表中的排位顺序决定先处理哪一个。
* Y* M: s- k+ W( E; T& F# F# w2 K1 S8 i
STM32 的中断分组可以有 5 种分组:如图
# h% E( h7 S0 n% E( X2 k7 O5 z# m% E8 O/ R0 J
1.jpg
  n  H( ~1 i, |6 K$ z
# B8 v7 O) H4 G% P5 HSTM32  中断分组库函数+ V/ P" r: o+ O1 \
NVIC_PriorityGroupConfig()
  Z7 M! J. F6 H* XNVIC_PriorityGroup 这个参数是用来选择设置分组的参数,我们知道它一共 可以分为 5 个组别如下图
$ y- h+ S1 `  e- a' E4 ]' C/ a5 G% A8 D5 e
2.jpg & R, e$ {! O* p

9 A2 B" d, F9 ]. e7 i9 X' o" HEXTI  外部中断, q2 R% J- |0 d( Z
STM32 的外部中断是有 16 条外部中断 通道,分别对应着每组 IO 口的 Px0 到 Px15。STM32 的每个 IO 口都能用作外部中断,一次性同时使用的外部 中断只能有16 个, 而且同时做外部中断的 IO 口序号也是不能相同的, 你使用 PA0做外部中断了,就不能同时使用 PB0 做外部中断了。6 t! K2 t& i2 w, |# n! A( s

3 \2 [" \# i  x! a外部中断的设置步骤:
* G3 I3 T3 U3 c7 Q: d" W) e1) 设置中断分组。
7 k6 O$ d/ o  r2) 配置 IO 口的模式。(比如你要使用下降沿触发,那么就选择上拉输入 模式,要使用上升沿触发,那么就选择下拉输入模式。)
' F* k  E3 W3 W$ I3) 选择要用作外部中断的 IO 口作为输入。' r. m2 t4 R8 W0 F; V
4) 开启要使用的中断通道并设置外部中断的参数(中断优先级、中 断触发模式)
# [  D# R( c6 Q0 J" ?$ E/ z' m: K. ]4 v  w
关于外部中断库函数介绍0 u% m: G' Q- e
1) RCC_APB2PeriphClockCmd()  我们要打开 GPIOE 及管脚复用的时钟。4 m. S+ q  j5 H" y: G
2) GPIO_Init() 函数   IO 模式设置为上拉输入:5 ~% i& D  V$ ~5 L1 P9 \0 o# {
3) GPIO_EXTILineConfig() 函数( e  x( H( F7 |4 X1 o5 A+ K
这个函数用来设置作为输入的 IO 口,它有两个输入参数: 第一个参数是使用选择 GPIO 的组别,我们要使用的是 PE2,所以设 置为:GPIO_PortSourceGPIOE。 第二个参数是设置 IO 的序号,我们使用的是 PE2,所以我们为:
# Z3 @/ L$ d$ j! U( t2 c" _GPIO_PinSource2 所以设置代码为:
: I3 B1 D5 N' ~: v# r3 x+ DGPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);* Y$ L0 A# \4 G9 n, E0 L! Q, i
' d% S" v9 G0 R, O( e" _
4) NVIC_Init() 函数  设置中断的优先级和打开总中断8 n' H- j+ R& U( C! L& o3 M
5) EXTI_Init() 函数  初始化外部中断
  Y( S+ z" N5 [) w% l6) EXTI_GetITStatus() 函数
/ _# o4 Z1 t/ h3 C/ T" _9 m7) 外部中断的中断函数# \0 B2 s$ c% [3 L0 U5 a* {, C* U
   EXTI0_IRQHandler2 j. q$ S) g. L5 S  H% ?
   EXTI1_IRQHandler
" J# [. \! Y! c- E2 W   EXTI2_IRQHandler) j# G3 X1 }# g7 H6 g
   EXTI3_IRQHandler$ |. O% `4 X5 ~$ L& O6 F4 z
8) EXTI_GetITStatus() 函数
+ i* ^& f/ u8 |& K8 o# }# }7 j5 S, y$ v* ^9 d- E
9) EXTI_ClearITPendingBit() 函数
9 m% Q+ y* b' F+ C+ _# |# J
3 ^  z- W: m5 s$ D9 o* o- G1)  初始化函数( ^  y# o- P2 B
void exti_init() //外部中断初始化
. k: j+ y1 s0 |7 ^4 w8 O, V! k{7 i0 h8 P; y1 _2 M
GPIO_InitTypeDef GPIO_InitStructure;; b1 \2 J7 h% r/ H0 y
EXTI_InitTypeDef EXTI_InitStructure;
5 [0 B$ }3 T  x: D- `  ~; C$ u/ TNVIC_InitTypeDef NVIC_InitStructure;
2 l3 ^% S! H7 _0 D* {, v/* 开启 GPIO 时钟 */
8 \( M4 b  ~8 L; wRCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);) }9 J% N- Y- N# L  m
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);, {% A3 H" A2 i: s' F' K
GPIO_InitStructure.GPIO_Pin=k_left;
! C; ^: j3 {5 F% HGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;6 o7 V9 A0 h1 k0 o( }+ |. T2 k, F
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;5 Z6 `8 P: G0 J9 B
GPIO_Init(GPIOE,&GPIO_InitStructure);
" v+ ^% p3 d' G7 i: HGPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);//选择
; _* q2 x7 i; v! q4 a: Q4 aGPIO 管脚用作外部中断线路
8 p( |& s5 `/ P+ W% r6 E, I, n, _( Q- A//此处一定要记住给端口管脚加上中断外部线路& G  o3 }$ p0 x- L: j- [1 v
/* 设置外部中断的模式 */3 _0 m; E6 H2 X6 R1 e: |5 [
EXTI_InitStructure.EXTI_Line=EXTI_Line2;
: v- [' b; w4 l6 j9 \EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
0 l8 o. Y7 Q9 a- J, k5 iEXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;1 J- u- J: |0 n5 g5 m+ F. p# z
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
" Y& R( y1 O6 t" [- ZEXTI_Init(&EXTI_InitStructure);* p5 i3 P- l) @' K. g8 C9 ?
/* 设置 NVIC 参数 */
  P( V, v! [( w/ |. zNVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);$ l& S& V5 o& v. d- O
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //打开 EXTI2
7 d2 L4 ~- Z8 X, P& P2 X* g# }的全局中断
; }. o& V4 ^% n' n+ j, w" TNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优
; j' C; E  ?& L& |4 \% Z% o( g先级为 0- l+ N1 b, c- O% i
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应
9 l: f  N$ D( _- P优先级为 0* `2 }/ K6 I: O0 C/ X
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
$ d  p! g* E8 \9 b+ _+ v7 {; FNVIC_Init(&NVIC_InitStructure);. B4 a! a1 C0 W( l( {' b) x1 f: v
}/ j6 n' l% \& H" A
* r) L) `% Z6 f2 @2 w- Z% G7 Z6 \
2)  中断函数( v& r6 n! K1 o2 M  Y
void EXTI2_IRQHandler() //外部中断 2 中断函数
( c" w# T$ k2 a4 i8 t{/ t1 {( B& f3 r8 E
if(EXTI_GetITStatus(EXTI_Line2)==SET)7 J0 L8 r5 l9 ?. V0 J! N
{: G3 _+ q+ f# I6 F7 G& N
EXTI_ClearITPendingBit(EXTI_Line0);//清除 EXTI 线路挂起位& ^" E3 d! n: E$ Q' f! o1 N+ f
delay_ms(10);//消抖处理: d& g7 g0 I0 ?) f& Y0 E
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==Bit_RESET)% K; r, h! T: _* J4 T# @* z% ~# Q
//k_left 按键按下
0 p) o1 M% i' F* D8 f( |{! ~/ l  T$ {- |/ a* c
if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_0)==Bit_RESET)( n9 z, k4 k! h& ?$ @+ g" [( q
{
0 ~7 {! H+ h- S//LED 熄灭
5 x( r( H2 k8 b; J! [# X0 X, J* `GPIO_SetBits(GPIOC,GPIO_Pin_0);) V/ ?6 L, y4 x( \1 T7 W. W% p
}
* v3 \/ L6 Y( i5 J9 \. @else
$ \6 X7 [% D- \5 Y{5 _* b3 {  {) D+ j+ k$ v9 a" z+ q
//LED 发光
" ]- x5 q+ @+ O' {' |0 @GPIO_ResetBits(GPIOC,GPIO_Pin_0);
0 d7 y" R5 Q; M. q! L) l/ }, d}
( L2 r$ k7 N) v' @* d# |+ t7 p3 P) p}
2 S3 L$ Y8 e* ewhile(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0);
. k- J2 I( p' l& G# N- V# }/ @7 s- r}. T: a; }- t2 e' T" T
}" p2 W: C# ~5 L2 F+ d

3 r( ]) N8 a. Q" p" J) Z- b' o6 y

评分

参与人数 1 ST金币 -5 收起 理由
Inc_brza -5

查看全部评分

收藏 评论1 发布时间:2018-1-16 18:25

举报

1个回答
Inc_brza 回答时间:2018-1-16 18:57:43
标题不合格,请尽快修改

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版