电子产业一站式赋能平台

PCB联盟网

搜索
查看: 347|回复: 0
收起左侧

单片机中断程序,如何被中断?

[复制链接]

856

主题

856

帖子

8459

积分

高级会员

Rank: 5Rank: 5

积分
8459
发表于 2024-8-19 07:42:00 | 显示全部楼层 |阅读模式

croiwgf1agw6402675032.gif

croiwgf1agw6402675032.gif

7 e; C  o- Z, z0 p2 p点击上方名片关注了解更多
6 y5 S5 h: W7 C% R( ^6 I
' D% A$ B% R! @1 Q来源 | 技术社区
( }: |4 }- W# x: i# ?; {9 y+ i3 A很多同学都存在这样的疑惑:如果外部中断来的频率足够快,上一个中断没有处理完成,新来的中断该如何处理?
9 I, V. a% o$ Z8 f! l; b# d& \中断一般是由硬件(例如外设、外部引脚)产生,当某种内部或外部事件发生时,MCU的中断系统将迫使 CPU 暂停正在执行的程序,转而去进行中断事件的处理,中断处理完毕后,又返回被中断的程序处,继续执行下去,所有的Cortex-M 内核系统都有一个用于中断处理的组件NVIC,主要负责处理中断,还处理其他需要服务的事件。嵌套向量式中断控制器(NVIC: Nested Vectored Interrupt Controller)集成在Cortex-M0处理器里,它与处理器内核紧密相连,并且提供了中断控制功能以及对系统异常的支持。9 K9 `* |) R. ^
处理器中的NVIC能够处理多个可屏蔽中断通道和可编程优先级,中断输入请求可以是电平触发,也可以是最小的一个时钟周期的脉冲信号。每一个外部中断线都可以独立的使能、清除或挂起,并且挂起状态也可以手动地设置和清除。& `4 n' a& q  y* L( h9 H
主程序正在执行,当遇到中断请求(Interrupt Request)时,暂停主程序的执行转而去执行中断服务例程(Interrupt Service Routine,ISR),称为响应,中断服务例程执行完毕后返回到主程序断点处并继续执行主程序。多个中断是可以进行嵌套的。正在执行的较低优先级中断可以被较高优先级的中断所打断,在执行完高级中断后返回到低级中断里继续执行,采用“咬尾中断”机制。
  U6 {' Z2 N! C( x5 [1 q; `

f2d2m1rz5lc6402675132.png

f2d2m1rz5lc6402675132.png
( |! S' |+ U% T5 l. E7 B  b
内核中断(异常管理和休眠模式等),其中断优先级则由SCB寄存器来管理,IRQ的中断优先级是由NVIC来管理。1 c$ ?/ P9 Z& `1 @$ j" B" v5 E
NVIC的寄存器经过了存储器映射,其寄存器的起始地址为0xE000E100,对其访问必须是每次32bit。% y6 ]8 L8 s) c  ]! I1 G
SCB寄存器的起始地址:0xE000ED00,也是每次32bit访问,SCB寄存器主要包含SysTick操作、异常管理和休眠模式控制。. G2 j; k$ q$ D$ K4 v3 R
NVIC具有以下特性:
) t$ F8 S* W3 o0 f灵活的中断管理:使能\清除、优先级配置硬件嵌套中断支持向量化的异常入口中断屏蔽1. 中断使能和清除使能
% P8 K+ E3 c2 u! N1 F" P- `arm将处理器的中断使能设置和清除设置寄存器分在两个不同的地址,这种设计主要有如下优势:一方面这种方式减少了使能中断所需要的步骤,使能一个中断NVIC只需要访问一次,同时也减少了程序代码并且降低了执行时间,另一方面当多个应用程序进程同时访问寄存器或者在读写操作寄存器时有操作其他的中断使能位,这样就有可能导致寄存器丢失,设置和清除分成两个寄存器能够有效防止控制信号丢失。
, m* v) S* k$ I5 h+ y* e* T

5w1155daayn6402675232.png

5w1155daayn6402675232.png
" D# {5 M- R2 }8 y' I9 a; L! R
因此我可以独立的操作每一个中断的使能和清除设置。
7 I6 [8 b+ _& i1.1 C代码*(volatile unsigned long) (0xE000E100) = 0x4 ; //使能#2中断/ n  C& p( T# N( T2 r
*(volatile unsigned long) (0xE000E180) = 0x4 ; //清除#2中断1.2 汇编代码__asm void Interrupt_Enable()
5 S  I+ m$ `8 R1 G' s5 [/ G{
/ T2 }, a% R& a LDR R0, =0xE000E100  ;  //ISER寄存器的地址4 f) E: x0 M) n
MOVS R1, #04         ;  //设置#2中断
+ _- v% @5 O/ f4 H STR R1, [R0]         ;  //使能中断#2
" ]: G& c* d+ {4 s: L) ]1 e}+ d! j, k4 @( W* N9 h" ^& r7 y' _  @% f
__asm void Interrupt_Disable()  W# U+ b  q+ Q. E) |& Y2 O
{
5 K' x! E, u. r( p- C+ @$ r- } LDR R0, =0xE000E180  ;  //ICER寄存器的地址& }1 B3 e" P( G9 }1 m- ^
MOVS R1, #04         ;  //设置#2中断
5 L8 R, T" x) \. ~' H+ `; @8 ? STR R1, [R0]         ;  //使能中断#2
" u9 {( O# v! |}1.3 CMSIS标准设备驱动函数//使能中断#IRQn
& P6 X- f  Z. s% v% Q__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
# C# ~+ ^% \1 s6 m' J{
8 q8 U( n7 I- ^5 K    if ((int32_t)(IRQn) >= 0) {
8 ~  l* x; T" n0 P        NVIC->ISER[0U] = (uint32_t)(1UL = 0) {+ A9 j% j( H1 A! \
        NVIC->ICER[0U] = (uint32_t)(1UL = 0) {
! B! a; x/ }$ K3 y5 C0 e5 I0 r        return((uint32_t)(((NVIC->ISER[0U] & (1UL 2. 中断挂起和清除挂起
5 }. V# I. }( f, d  |) Y如果一个中断发生了,却无法立即处理,这个中断请求将会被挂起。挂起状态保存在一个寄存器中,如果处理器的当前优先级还没有降低到可以处理挂起的请求,并且没有手动清除挂起状态,该状态将会一直保持。
0 X5 E/ i/ g' G# G可以通过操作中断设置挂起和中断清除挂起两个独立的寄存器来访问或者修改中断挂起状态,中断挂起寄存器也是通过两个地址来实现设置和清除相关位。这使得每一个位都可以独立修改,并且无需担心在两个应用程序进程竞争访问时出现的数据丢失。8 ?8 g% P3 l6 F9 C) `1 x

0odu5vlkhyc6402675332.png

0odu5vlkhyc6402675332.png
6 y3 m) r9 x$ f' F9 k/ e# W) x4 D  T
中断挂起状态寄存器允许使用软件来触发中断。如果中断已经使能并且没有被屏蔽掉,当前还没有更高优先级的中断在运行,这时中断的服务程序就会立即得以执行。2.1 C代码*(volatile unsigned long)(0xE000E100) = 0x4 ; //使能中断#2
' F( I/ `* |# ^  ~. D0 B9 n9 Y1 i*(volatile unsigned long)(0xE000E200) = 0x4 ; //挂起中断#2
% e, Z  J% u9 b3 Z) b*(volatile unsigned long)(0xE000E280) = 0x4 ; //清除中断#2的挂起状态2.2 汇编代码__asm void Interrupt_Set_Pending()
9 k+ ^: ^0 p# H+ x: J{3 {4 s4 e# @6 \4 Q  p# |9 ?" m
LDR R0, =0xE000E100   ;  //设置使能中断寄存器地址
; G+ z. F. L$ ~ MOVS R1, #0x4         ;  //中断#2
, E+ i  H0 N, ^4 U STR R1, [R0]          ;  //使能#2中断6 V9 l) [: v8 d2 k/ b4 x, d- q% y8 r
LDR R0, =0xE000E200   ; //设置挂起中断寄存器地址% g7 \" P9 x- I
MOVS R1, #0x4         ;  //中断#2
1 D( t3 w: p( |& N9 s STR R1, [R0]          ;  //挂起#2中断
/ z: C2 B2 ?2 E) [}
* l9 m7 X5 i" f% B; Y__asm void Interrupt_Clear_Pending()
" q0 e; A' J( o2 l' x7 z4 z* ^& Y: _{$ {% w- g' D. h
LDR R0, =0xE000E100   ;  //设置使能中断寄存器地址4 o9 e0 o6 }3 h8 S
MOVS R1, #0x4         ;  //中断#2* h: Q4 n$ `. k
STR R1, [R0]          ;  //使能#2中断
. R, \/ ]* z( a" T5 i: n/ l( B LDR R0, =0xE000E280   ; //设置清除中断挂起寄存器地址! }! X1 Q8 |5 u" P
MOVS R1, #0x4         ;  //中断#29 o7 B% y& x4 [/ d) j7 y
STR R1, [R0]          ;  //清除#2的挂起状态
6 p" F3 ^4 j( @}2.3 CMSIS标准设备驱动函数//设置一个中断挂起
! c0 \# z5 ?* \4 [- H' N$ J( [8 g__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) # Y2 `  Y2 O. [# z' R
{
! w2 J( r, X0 P( Z. V    if ((int32_t)(IRQn) >= 0) {
# l# w" j+ X( a6 t  |2 D" N" k        NVIC->ISPR[0U] = (uint32_t)(1UL = 0) {2 }2 x( D; d( H6 G
        NVIC->ICPR[0U] = (uint32_t)(1UL = 0) {
) M1 |. g8 K& w% l6 @        return((uint32_t)(((NVIC->ISPR[0U] & (1UL NVIC属于处理器内核部分,因此在MM32 MCU芯片的用户手册中只有简单的提及,没有重点讲述,需要深入了解相关寄存器和功能需要参考《Cortex-M0技术参考手册》。' o+ q+ \! \; G( q

kstcr1bnong6402675432.jpg

kstcr1bnong6402675432.jpg

2 X1 R, t6 S* g# i0 I) b" ~

0mtna2b22ym6402675532.jpg

0mtna2b22ym6402675532.jpg

# f7 ]7 l) R! s0 e1 S+ E1 c声明:
8 ]& J9 B# h) O+ X/ n声明:本号对所有原创、转载文章的陈述与观点均保持中立,推送文章仅供读者学习和交流。文章、图片等版权归原作者享有,如有侵权,联系删除。投稿/招聘/推广/宣传 请加微信:woniu26a推荐阅读▼
" S. S2 ~2 e3 u% j2 \* [: I电路设计-电路分析: b7 J1 ?7 m: t) L; y
emc相关文章
. n6 L0 ^/ D5 \3 k电子元器件& O- I6 n; i& s1 }( V' ?
后台回复“加群”,管理员拉你加入同行技术交流群。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表