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

STM32中断详解

[复制链接]
STMCU-管管 发布时间:2020-10-22 14:33
STM32中断详解
, c7 M. r3 k8 w7 c! `6 V0 M
( x, z4 O) a* \. k: i# b9 [
1 异常类型
* z% j7 r' u5 d( x
CM3内核支持256个中断,其中 16个内核中断和240个外部中断,并具有256级可编程中断设置。STM32并没有使用CM3的全部内容,而是使用了一部分。STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程中断优先级。STM32F103 在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中系统异常有 8 个(如果把 Reset 和 HardFault 也算上的话就是 10 个),外部中断有 60个。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。有关具体的系统异常和外部中断可在标准库文件 stm32f10x.h 这个头文件查询到,在 IRQn_Type 这个结构体里面包含了 F103 系列全部的异常声明。F103系统异常清单见下表。" A3 f- L- v. O& C, `& U3 N. t1 S
5 {/ j) D0 B. D- G/ j$ S* H
11.png
, S5 P& V; ~- r

' T3 c0 K1 p' \& m- I" o
F103 外部中断清单见下表。% S: @& e* w! B* D
12.png
13.png
…) u+ C. Z6 p! y9 |' V
  D% X$ X" T) U

3 i4 J* R) D5 N* u- y
2 NVIC简介

+ @/ k. Q# H' U# {在讲如何配置中断优先级之前,我们需要先了解下 NVIC。 NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对 Cortex-M3 内核里面的 NVIC 进行裁剪,把不需要的部分去掉,所以说 STM32 的 NVIC 是 Cortex-M3 的 NVIC 的一个子集。( X6 e$ N' d: V
$ U2 l$ D( |$ P5 [3 C( q
" t2 g  v. D7 A+ b" ~- S2 `1 W/ i
NVIC 寄存器简介6 m) ], {/ w- k, n
在固件库中, NVIC 的结构体定义可谓是颇有远虑,给每个寄存器都预留了很多位,恐怕为的是日后扩展功能。不过 STM32F103 可用不了这么多,只是用了部分而已,具体使用了多少可参考《 Cortex-M3 内核编程手册》的NVIC 寄存器映射。

7 E" C8 O' N6 V- Q" S& J9 o: N
14.png
- z( |8 M& m7 ~, k+ s3 w. V* ]
[ps]NVIC 结构体定义,来自固件库头文件: core_cm3.h。
2 ^+ e7 K3 B# C# k$ i$ V' Z在配置中断的时候我们一般只用 ISER、 ICER 和 IP 这三个寄存器, ISER 用来使能中断, ICER 用来失能中断,IP 用来设置中断优先级。
, @; O$ ?- ]) z3 y( d, o) l5 S+ b% L" A  {
NVIC 中断配置固件库) K1 K! \" K# _* V! s  S5 o2 }% ^
固件库文件 core_cm3.h 的最后,还提供了NVIC 的一些函数,这些函数遵循 CMSIS 规则,只要是 Cortex-M3 的处理器都可以使用,符合CMSIS标准的NVIC库函数具体如下表。

5 J! n5 O# ]1 ~, N4 O6 ^. }0 }
15.png
4 N2 ^9 R, {( I' X7 x7 `( g; v
这些库函数我们在编程的时候用的都比较少,甚至基本都不用。+ ^0 J' K6 ?0 R

0 {+ r2 e3 R2 Y6 Z8 B3 优先级的定义
# D" V5 `* V7 T. \
优先级定义
1 e0 e; i+ n. Z在 NVIC 有一个专门的寄存器:中断优先级寄存器 NVIC_IPRx,用来配置外部中断的优先级, IPR 宽度为 8bit,原则上每个外部中断可配置的优先级为 0~255,数值越小,优先级越高。但是绝大多数 CM3 芯片都会精简设计,以致实际上支持的优先级数减少,在F103 中,只使用了高 4bit,F103 使用 4bit 表达优先级如下所示。

' I: k* G( a1 U6 g' f2 a% p, o
4 h7 P+ g, C2 l

* ~1 y8 [# k3 ~用于表达优先级的这 4bit,又被分组成抢占优先级和子优先级。如果有多个中断同时响应,抢占优先级高的就会抢占抢占优先级低的优先得到执行,如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高。: I: e# O0 _# Q! Q% R" W) p
0 w- P* B% q  P

" ]& ?% m7 e* I( ~8 X) m优先级分组/ R: w4 b" x: E0 d* z* G
优先级的分组由内核外设 SCB 的应用程序中断及复位控制寄存器 AIRCR 的PRIGROUP[10:8]位决定, F103 分为了 5 组,具体如下:主优先级=抢占优先级。优先级分组如下表所示。
7 ^1 I# X7 l* ^! j) G% e
16.png # Y; w# N/ f, E; p; N
设置优先级分组可调用库函数NVIC_PriorityGroupConfig()实现,有关 NVIC 中断相关的库函数都在库文件 misc.c 和 misc.h 中。优先级分组真值表如下表。9 _7 J+ ?& x0 T" Q/ Z! V
17.png 9 ]$ A# I, T8 v1 R
" T$ M% o" Z* {. Y% a- y/ ], w
中断编程
( a6 w& i# \  N$ G1 z/ h' g( \2 ^
18.png
# @) E" q* F, o2 B# w
. \( E8 ]0 P: v6 u" A- {9 @
在配置每个中断的时候一般有 3 个编程要点:4 z2 K& J& d' T) H; a
1、使能外设某个中断。这个具体由每个外设的相关中断使能位控制。比如串口有发送完成中断,接收完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。
0 G/ C! Z  ], a  H8 h2、初始化 NVIC_InitTypeDef结构体,配置中断优先级分组,设置抢占优先级和子优先级,使能中断请求。 NVIC_InitTypeDef结构体在固件库头文件 misc.h 中定义。2 {% o! R4 X6 g. F' g  o1 L
  1. 5 U: p+ d9 f/ ]4 J$ V
  2. typedef struct {
      |6 i: G* j9 y" I, H% E( G+ b
  3.     uint8_t NVIC_IRQChannel; // 中断源9 g: j1 u# e% o/ s
  4.     uint8_t NVIC_IRQChannelPreemptionPriority;// 抢占优先级6 L+ I& R; l4 N9 L& \4 C
  5.     uint8_t NVIC_IRQChannelSubPriority; // 子优先级  V; s( \) @, W. l! T6 R( Z
  6.     FunctionalState NVIC_IRQChannelCmd; // 中断使能或者失能
    ( o& U+ g1 `4 R# t2 H' b
  7. } NVIC_InitTypeDef;
复制代码

/ |; |( C7 [# `& G) s2 ~  C) e* i
2 \4 k: G7 t. r/ a有关 NVIC 初始化结构体的成员我们一一解释下:( I: B2 f  s' Q5 f( R2 I7 h
1) NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。具体的成员配置可参考 stm32f10x.h 头文件里面的 IRQn_Type 结构体定义,这个结构体包含了所有的中断源。( W6 y( u2 R( H- n8 _& L6 |- C' d

  1. 7 W2 G, p- r0 v: y; T
  2. typedef enum IRQn {0 i5 V( }3 v" t; {
  3.      //Cortex-M3 处理器异常编号2 H3 j! L. J3 j2 s' D6 g. [
  4.      NonMaskableInt_IRQn = -14,7 a9 U/ u! W4 y* ~* Z; W
  5.      MemoryManagement_IRQn = -12,
    % G+ L: D# C0 C" _) r9 ]; {
  6.      BusFault_IRQn = -11,
    5 h. e4 q* k. {' Z, v& ]
  7.      UsageFault_IRQn = -10,
    # }+ J9 _( F% ?4 t: Z
  8.      SVCall_IRQn = -5,
    * ^/ U4 v$ {0 ^" j: u
  9.      DebugMonitor_IRQn = -4,5 J- G3 O$ j  [7 J$ t- [
  10.      PendSV_IRQn = -2,
    " V! Q. r/ V- {; d; L- s9 J
  11.      SysTick_IRQn = -1,
    . I! w8 a0 A* ^0 F  P7 T
  12.      //STM32 外部中断编号% F, }* {! P& n. L8 Z6 p, l* m
  13.      WWDG_IRQn = 0,
    ; a, j0 K8 b4 r9 w* {, [& }& p+ y
  14.      PVD_IRQn = 1,  }! X4 T2 o0 S, o& Y
  15.      TAMP_STAMP_IRQn = 2,8 C& w: I  h7 W' }
  16. 6 A- B; P: F# |4 L* a! o9 g, Y
  17.      //限于篇幅,中间部分代码省略,具体的可查看库文件 stm32f10x.h& M4 E/ ^; R) G3 K

  18. / b7 |' M1 k9 F
  19.      DMA2_Channel2_IRQn = 57,9 v; ?- c! k6 }1 B1 ~: _+ s# @
  20.      DMA2_Channel3_IRQn = 58,
    " q0 F! m) |1 K& h( d' u
  21.      DMA2_Channel4_5_IRQn = 59
    . w* \$ f2 R# s8 N6 L
  22. } IRQn_Type;
复制代码

0 s; [# n3 n* i: A( f% O3 D7 [& `- v  H- n
2)NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,具体参考表6优先级分组真值表。8 Y7 x* P& U( ]6 Q$ Y- O- C/ t
3)NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定,具体参考表6优先级分组真值表。
1 ~9 ~7 k+ l' @4)NVIC_IRQChannelCmd:中断使能( ENABLE)或者失能( DISABLE)。操作的是 NVIC_ISER 和 NVIC_ICER 这两个寄存器。2 Y& t& Y3 V) T5 H% z+ M* ~6 L( o

( H/ y  w) L" m4 `1 J3、编写中断服务函数- A5 T6 W$ `6 U( B3 i) g
在启动文件startup_stm32f10x_hd.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,为了方便管理我们把中断服务函数统一写在 stm32f10x_it.c 这个库文件中。关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。
4 h# x4 s4 R* P4 ]( |# J/ A# B+ l# G

1 F. v4 f/ C( s  y# J7 E- q! Y; C9 f, T1 X5 B% i6 G8 m

4 p( |5 b+ L* s; S0 e2 A1 h8 J5 c. F1 d: Q4 D3 j
赞 收藏 评论1 发布时间:2020-10-22 14:33

举报

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