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

stm32——STM32 中断

[复制链接]
feixiang20 发布时间:2018-1-16 18:25
本帖最后由 feixiang20 于 2018-1-16 20:33 编辑
$ j* `( a, J( i+ K7 W1 `0 {9 E) X! @/ h- p8 V, Z
这次实验,我们将学习如何使用 STM32 的外部输入中断。在前几次的学习中,我们掌握了 STM32 的 IO 口最基本的操作。 本次实验我们将介绍如何将STM32 的 IO 口作为外部中断输入,在本实验中,我们将以中断的方式,实现按键控制 LED 亮灭的功能 。 实验目标:
$ O* x2 V( C4 E4 d: ~2 [1、 了解 STM32 的中断模式 NVIC 。
! L5 y* c+ Y" l4 W" z2、 了解外部中断的使用方式 。) M( `" \! b% [% C; }1 F, M

  U$ C7 K. \9 a9 }中断的概念: V) g; K6 A! w
如果学员有单片机的基础,那么就会知道中断的概念。所谓中断是指 CPU 在执行当前程序的过程中,由于某种随机出现的外设请求或 CPU 内部的异常事件,使 CPU 暂停正在执行的程序而转去 执行相应的服务处理程序;当服务处理 程序运行完毕后,CPU 再返回到暂停处继续执行原来的程序。 而有些中断还能够被其他高优先级的中断所中断,那么这种情况又叫做中断的嵌套。1 Z: P* J/ X# M: r$ y6 m- \4 p
% w5 i0 I; f& P. V, W$ F8 i, W# u0 z
STM32  的中断1) STM32  中断分组3 u) a  ]' \& M# K+ x
STM32 的中断一共有 68 个可屏蔽中断通道16 个可编程的优先等级;什么叫做可编程等级呢? 首先我们来看一下STM32 中断等级式,STM32 使用一个 4 位寄存器 来设置中断等级的,4 位长度可以设置 16 个优先等级(2 的 4 次方等于 16); 而这个优先等级是可以设置的,所以叫做可编程等级。而且呢,这个 4 位长 度的优先等级还可以分为两部分,一部分叫做抢占优先级,一部分叫做响应 优先(些资料也叫做亚优先级) (比如说: 4 位里面设置 1 位抢占优先级,3 位的响应优先级。)在这里大家可能有点糊涂了,分成抢占优先级和响应优先级又是什么用呢?' r; b0 s. L2 @% R# T4 L3 E: @
在 STM32 的 NVIC 中规定: 抢占优先级高的可以中断抢占优先级比它低 的中断函数,不过相同抢占优先级的之间是不能相互中断的。响应优先级 之间是不能相互中断的,有人或许既然都不能中断了,那响应优先级还有什 么意义呢?如果这两个中断同时到达,则中断控制根据他们的响应优先级 高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等, 则根据他们在中断表中的排位顺序决定先处理哪一个。/ Z2 u6 _/ H' a, H1 {+ f/ O+ H+ b

- t% }6 _' Q0 ~STM32 的中断分组可以有 5 种分组:如图
2 f  p: Z! v3 t5 _& t2 q/ y- f6 v- a" f/ r5 N& q; q
1.jpg / E) _" C! Z8 a0 t. T# f; l

, T4 e, ^' _" n- {STM32  中断分组库函数4 W1 M# v  l! E( p7 b
NVIC_PriorityGroupConfig()3 j- e$ @% S& i5 X9 w
NVIC_PriorityGroup 这个参数是用来选择设置分组的参数,我们知道它一共 可以分为 5 个组别如下图
" |8 L3 M6 x2 m
1 K4 @1 {) a/ D/ N8 B. |; `7 g% Y$ a 2.jpg , ^2 @, j. r$ L/ R2 n

% H- p: f* o' A! }. y3 ~EXTI  外部中断
/ U/ @- R# m  eSTM32 的外部中断是有 16 条外部中断 通道,分别对应着每组 IO 口的 Px0 到 Px15。STM32 的每个 IO 口都能用作外部中断,一次性同时使用的外部 中断只能有16 个, 而且同时做外部中断的 IO 口序号也是不能相同的, 你使用 PA0做外部中断了,就不能同时使用 PB0 做外部中断了。/ I: r  M; \3 y# v4 I/ w& @
) A6 N5 s, }) l' N& o
外部中断的设置步骤:( G* G$ {" ?' }) D6 R' S4 \! m
1) 设置中断分组。 ; P9 h( g% n) o# b$ E! l5 B+ T
2) 配置 IO 口的模式。(比如你要使用下降沿触发,那么就选择上拉输入 模式,要使用上升沿触发,那么就选择下拉输入模式。): ^1 A+ ]& u$ s0 a3 T+ f2 T( O
3) 选择要用作外部中断的 IO 口作为输入。
" D  X4 g) ?5 ~; r& g8 z- x4) 开启要使用的中断通道并设置外部中断的参数(中断优先级、中 断触发模式)/ z6 {2 |- q2 {, E' k2 W

( w* t. L; Y4 j  T6 y8 M3 N关于外部中断库函数介绍
  \5 O; e( Y8 A1 p1 T1) RCC_APB2PeriphClockCmd()  我们要打开 GPIOE 及管脚复用的时钟。
3 e, \* b. d% K% Y2) GPIO_Init() 函数   IO 模式设置为上拉输入:) ~$ i# `) P7 l, N
3) GPIO_EXTILineConfig() 函数; \) C- [# [+ q& ~
这个函数用来设置作为输入的 IO 口,它有两个输入参数: 第一个参数是使用选择 GPIO 的组别,我们要使用的是 PE2,所以设 置为:GPIO_PortSourceGPIOE。 第二个参数是设置 IO 的序号,我们使用的是 PE2,所以我们为:' A7 T) P0 m8 S7 D9 L! p- c
GPIO_PinSource2 所以设置代码为:
. F3 ]. |' K0 _& H/ h# J- k5 H7 ~GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);$ N& ]1 i) T9 `" t% f% D

+ {: N# D+ d( p* L9 v4) NVIC_Init() 函数  设置中断的优先级和打开总中断7 f/ @1 L" N. I& D* D
5) EXTI_Init() 函数  初始化外部中断  [6 n4 A4 u4 i& a
6) EXTI_GetITStatus() 函数, K* F2 T& N( N3 G/ _
7) 外部中断的中断函数
; w! u6 M! d: ~$ |1 s3 V  }0 T( }   EXTI0_IRQHandler
1 M5 d' U5 F, E! H. g* s7 n0 w& ?   EXTI1_IRQHandler
& c* Z. C& `4 M0 I: e   EXTI2_IRQHandler
9 M& q6 i0 _, Y. E% p! |$ W$ ?   EXTI3_IRQHandler( S! f8 Z; d% l, o  |; J
8) EXTI_GetITStatus() 函数
2 S5 S$ O# b. S; N4 X# ]
( T# D3 K- \! a9) EXTI_ClearITPendingBit() 函数, v4 d( N$ L4 q  \0 f

1 S, U2 ?' E' ^# j* N- y2 g1)  初始化函数
9 o' |  q3 I7 L6 x1 {0 {void exti_init() //外部中断初始化" f& G  |/ c* H& C# ~
{8 c. V  E* x2 b( e2 f2 d) ]: [1 }
GPIO_InitTypeDef GPIO_InitStructure;, ]" g5 r, S- l/ h" Q! G& S6 |. U
EXTI_InitTypeDef EXTI_InitStructure;
5 n- m2 _9 p# [9 n; lNVIC_InitTypeDef NVIC_InitStructure;
( A4 C- D" x' c8 c3 Q4 ?- F/* 开启 GPIO 时钟 */& Q1 i+ `+ W6 B1 S9 ]
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);3 s5 `) n$ c3 }
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);& i; m$ j/ U% J' a
GPIO_InitStructure.GPIO_Pin=k_left;  [- C. }5 `" e, J. e( j
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
8 k' t4 k3 l0 N  TGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
' D: ~* S. D, C) rGPIO_Init(GPIOE,&GPIO_InitStructure);) L) _8 r! N# i0 N
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);//选择
$ b6 }$ ^, p% o4 F- |1 ZGPIO 管脚用作外部中断线路
9 g. `/ [! O. v( z1 Z6 [//此处一定要记住给端口管脚加上中断外部线路) ~; R4 T8 K- z
/* 设置外部中断的模式 */1 Y& w' S. ?% G: Z
EXTI_InitStructure.EXTI_Line=EXTI_Line2;' W+ w+ c( e2 [- R
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
; l) b$ p6 a& H7 o- M# h+ w4 oEXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
3 l/ u: p; Q( {- b# e# [7 j" R1 WEXTI_InitStructure.EXTI_LineCmd = ENABLE;# F3 N: N; L( E; A
EXTI_Init(&EXTI_InitStructure);* L  \' o7 w4 {, Z- w9 S6 E9 P
/* 设置 NVIC 参数 */7 T4 C3 h. y- `8 [/ |
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);7 T$ v# k. q' w: d6 J8 G) h
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //打开 EXTI2
2 ]; b, S3 h( g: f, T) x7 v的全局中断
( _' Y: ^$ d8 Y' |8 S' c; j% B. QNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优; ~1 a8 y7 ?7 E( C' x6 U+ u
先级为 03 F+ S! H4 x/ M  Z; w7 y
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应+ s0 j2 A. k. h1 c, h: W$ k
优先级为 0
  J, L/ N; S- H+ h2 RNVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
- G0 j7 |% b: d" A2 `2 P7 j9 QNVIC_Init(&NVIC_InitStructure);
  S; ^% w& H$ p}/ _3 h8 v# B7 V  ]" f+ N

& w/ k! Z$ X4 q: w8 b- j' _2)  中断函数
0 Q: L7 W% k# P( S# F3 m6 N: ?2 lvoid EXTI2_IRQHandler() //外部中断 2 中断函数2 l4 H1 Y, q; [' [$ d
{
0 f& R; P+ U: cif(EXTI_GetITStatus(EXTI_Line2)==SET)- U% [  t' X9 i6 v& n$ }% {9 k7 C+ i
{2 Z+ s: \! u5 v* F8 ^$ j
EXTI_ClearITPendingBit(EXTI_Line0);//清除 EXTI 线路挂起位9 @4 m  q& K3 f' Q5 t# D4 G
delay_ms(10);//消抖处理4 q. d5 ^4 G8 f' k3 J0 T) k
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==Bit_RESET)
, d" E' m8 X/ S$ r" m//k_left 按键按下& S% U5 @; \; F( R
{0 E* J6 L& Z; |8 ?
if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_0)==Bit_RESET)9 a& Q) {3 K4 |: w* I4 g6 ]
{9 C4 v; T0 T. o# [# k( `
//LED 熄灭
! V" |# @6 b1 K9 n/ N) ?GPIO_SetBits(GPIOC,GPIO_Pin_0);
1 q6 L0 d" Q. f: n, ~}
, C: Z+ t6 }5 m, M: {% E, felse
7 Z  C5 ]! @% L/ X4 }6 x8 g{  g2 l4 L4 d) u- A# l* D
//LED 发光
) c$ s) `, C7 {7 [3 ^/ qGPIO_ResetBits(GPIOC,GPIO_Pin_0);
6 ^$ F. h1 S0 p/ \- v, G' g6 l}
# J- y. D2 Y& a! G* N  Z7 |}
. |3 a' h4 \1 rwhile(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0);6 G3 e$ Q$ u' R3 O" R& \; ^
}& u1 p0 \/ A! v- g2 M6 H$ s1 A
}
4 G! D9 L0 @6 h; \+ g6 P( f/ G1 i  ~

评分

参与人数 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 手机版