電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 171|回復(fù): 0
收起左側(cè)

單片機(jī)中斷程序,如何被中斷?

[復(fù)制鏈接]

531

主題

531

帖子

3817

積分

四級會員

Rank: 4

積分
3817
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-8-19 07:42:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
6 I" r( |3 {5 N# h: n
點(diǎn)擊上方名片關(guān)注了解更多
( r" ?. A- o/ z  P; g5 p, ^/ O; A& s7 v
來源 | 技術(shù)社區(qū)$ G5 g5 i. r8 z1 }* m
很多同學(xué)都存在這樣的疑惑:如果外部中斷來的頻率足夠快,上一個(gè)中斷沒有處理完成,新來的中斷該如何處理?
- M) @6 Y% T, Y, T中斷一般是由硬件(例如外設(shè)、外部引腳)產(chǎn)生,當(dāng)某種內(nèi)部或外部事件發(fā)生時(shí),MCU的中斷系統(tǒng)將迫使 CPU 暫停正在執(zhí)行的程序,轉(zhuǎn)而去進(jìn)行中斷事件的處理,中斷處理完畢后,又返回被中斷的程序處,繼續(xù)執(zhí)行下去,所有的Cortex-M 內(nèi)核系統(tǒng)都有一個(gè)用于中斷處理的組件NVIC,主要負(fù)責(zé)處理中斷,還處理其他需要服務(wù)的事件。嵌套向量式中斷控制器(NVIC: Nested Vectored Interrupt Controller)集成在Cortex-M0處理器里,它與處理器內(nèi)核緊密相連,并且提供了中斷控制功能以及對系統(tǒng)異常的支持。* r+ k7 B: ^0 ~- J, {: n
處理器中的NVIC能夠處理多個(gè)可屏蔽中斷通道和可編程優(yōu)先級,中斷輸入請求可以是電平觸發(fā),也可以是最小的一個(gè)時(shí)鐘周期的脈沖信號。每一個(gè)外部中斷線都可以獨(dú)立的使能、清除或掛起,并且掛起狀態(tài)也可以手動地設(shè)置和清除。
' K) x) n; s/ d主程序正在執(zhí)行,當(dāng)遇到中斷請求(Interrupt Request)時(shí),暫停主程序的執(zhí)行轉(zhuǎn)而去執(zhí)行中斷服務(wù)例程(Interrupt Service Routine,ISR),稱為響應(yīng),中斷服務(wù)例程執(zhí)行完畢后返回到主程序斷點(diǎn)處并繼續(xù)執(zhí)行主程序。多個(gè)中斷是可以進(jìn)行嵌套的。正在執(zhí)行的較低優(yōu)先級中斷可以被較高優(yōu)先級的中斷所打斷,在執(zhí)行完高級中斷后返回到低級中斷里繼續(xù)執(zhí)行,采用“咬尾中斷”機(jī)制。
# ?+ G# C* ?  X0 L: R 8 t1 e- Z1 {; `4 s, i- z
內(nèi)核中斷(異常管理和休眠模式等),其中斷優(yōu)先級則由SCB寄存器來管理,IRQ的中斷優(yōu)先級是由NVIC來管理。
; Q% w0 k5 r) O' Z) \NVIC的寄存器經(jīng)過了存儲器映射,其寄存器的起始地址為0xE000E100,對其訪問必須是每次32bit。
3 ~. [' T* T* n6 ]SCB寄存器的起始地址:0xE000ED00,也是每次32bit訪問,SCB寄存器主要包含SysTick操作、異常管理和休眠模式控制。
. d' g& y. e: ZNVIC具有以下特性:8 ]1 h3 U2 J1 I% Z. E: }
靈活的中斷管理:使能\清除、優(yōu)先級配置硬件嵌套中斷支持向量化的異常入口中斷屏蔽1. 中斷使能和清除使能
6 I7 x" \  _2 {2 _+ }arm將處理器的中斷使能設(shè)置和清除設(shè)置寄存器分在兩個(gè)不同的地址,這種設(shè)計(jì)主要有如下優(yōu)勢:一方面這種方式減少了使能中斷所需要的步驟,使能一個(gè)中斷NVIC只需要訪問一次,同時(shí)也減少了程序代碼并且降低了執(zhí)行時(shí)間,另一方面當(dāng)多個(gè)應(yīng)用程序進(jìn)程同時(shí)訪問寄存器或者在讀寫操作寄存器時(shí)有操作其他的中斷使能位,這樣就有可能導(dǎo)致寄存器丟失,設(shè)置和清除分成兩個(gè)寄存器能夠有效防止控制信號丟失。
! l0 L4 U) }8 U6 z" a% H4 m # i9 e( ]& O6 Z3 R. X' h
因此我可以獨(dú)立的操作每一個(gè)中斷的使能和清除設(shè)置。
# C8 N: z: z1 `+ b- \2 _  I1.1 C代碼*(volatile unsigned long) (0xE000E100) = 0x4 ; //使能#2中斷; Y  s% K+ s0 K3 g9 Y5 C6 P
*(volatile unsigned long) (0xE000E180) = 0x4 ; //清除#2中斷1.2 匯編代碼__asm void Interrupt_Enable()
% _( j- \; E3 W8 I{
& ~8 |* X7 _" j2 c LDR R0, =0xE000E100  ;  //ISER寄存器的地址
3 ~% j9 O. ?0 V7 d/ E* \4 b' \ MOVS R1, #04         ;  //設(shè)置#2中斷
; S" O7 m7 P) A% c6 |6 i STR R1, [R0]         ;  //使能中斷#28 }7 x* Y! Q% [6 r' y; b2 p
}
0 V( ?+ K4 @* z) h' [9 z: f: R__asm void Interrupt_Disable()
0 h/ |6 y9 X- z3 R; m, ^  O4 [{" e* h4 B  e+ o
LDR R0, =0xE000E180  ;  //ICER寄存器的地址
) @. l* s' v  G5 `5 G MOVS R1, #04         ;  //設(shè)置#2中斷$ Y7 y6 H! }5 }* H- @7 l- C/ [4 r
STR R1, [R0]         ;  //使能中斷#2
5 f$ J3 s0 \: ^4 y}1.3 CMSIS標(biāo)準(zhǔn)設(shè)備驅(qū)動函數(shù)//使能中斷#IRQn
0 ~0 F, L( ~- m$ C0 a& k__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) % I8 t; a2 e  p0 v: U$ x
{2 _& A" {8 q+ _. F
    if ((int32_t)(IRQn) >= 0) {
# e0 |4 X' v4 {9 s        NVIC->ISER[0U] = (uint32_t)(1UL = 0) {  ^0 N6 ~; I! q5 W3 u
        NVIC->ICER[0U] = (uint32_t)(1UL = 0) {
/ X# D" o# _" ~        return((uint32_t)(((NVIC->ISER[0U] & (1UL 2. 中斷掛起和清除掛起. t& ]/ M. t" c  N
如果一個(gè)中斷發(fā)生了,卻無法立即處理,這個(gè)中斷請求將會被掛起。掛起狀態(tài)保存在一個(gè)寄存器中,如果處理器的當(dāng)前優(yōu)先級還沒有降低到可以處理掛起的請求,并且沒有手動清除掛起狀態(tài),該狀態(tài)將會一直保持。
% @, c/ x  J* u  \7 J1 ^  x可以通過操作中斷設(shè)置掛起和中斷清除掛起兩個(gè)獨(dú)立的寄存器來訪問或者修改中斷掛起狀態(tài),中斷掛起寄存器也是通過兩個(gè)地址來實(shí)現(xiàn)設(shè)置和清除相關(guān)位。這使得每一個(gè)位都可以獨(dú)立修改,并且無需擔(dān)心在兩個(gè)應(yīng)用程序進(jìn)程競爭訪問時(shí)出現(xiàn)的數(shù)據(jù)丟失。
! b( j  N. p2 ^( l1 J& y) d) M " W/ ~' W  k; O( t: [( \
中斷掛起狀態(tài)寄存器允許使用軟件來觸發(fā)中斷。如果中斷已經(jīng)使能并且沒有被屏蔽掉,當(dāng)前還沒有更高優(yōu)先級的中斷在運(yùn)行,這時(shí)中斷的服務(wù)程序就會立即得以執(zhí)行。2.1 C代碼*(volatile unsigned long)(0xE000E100) = 0x4 ; //使能中斷#2
) V3 ~( j  P" K( s*(volatile unsigned long)(0xE000E200) = 0x4 ; //掛起中斷#2
& z/ E3 E# P8 M  R*(volatile unsigned long)(0xE000E280) = 0x4 ; //清除中斷#2的掛起狀態(tài)2.2 匯編代碼__asm void Interrupt_Set_Pending()
" C$ F: s3 F9 G. A1 [! E# C8 t{9 P$ D9 o' |5 \0 X
LDR R0, =0xE000E100   ;  //設(shè)置使能中斷寄存器地址! S) t* U5 e4 {0 }( t# U. J1 o' ~
MOVS R1, #0x4         ;  //中斷#2
; s7 o( B; Y! V8 D, `% U STR R1, [R0]          ;  //使能#2中斷
5 k6 n8 |" `! m  O LDR R0, =0xE000E200   ; //設(shè)置掛起中斷寄存器地址
& h  ]. z0 X+ t+ ]/ B MOVS R1, #0x4         ;  //中斷#2, ^2 T0 Y8 n& ?% J+ }
STR R1, [R0]          ;  //掛起#2中斷
! u5 Z' [% [# N- u: S}2 h( F! X6 B7 t# C/ s  I' Y
__asm void Interrupt_Clear_Pending()
- {% Q' n+ K! f. }3 ^( Q{
7 o% G) |: v! H! a( a LDR R0, =0xE000E100   ;  //設(shè)置使能中斷寄存器地址
9 l' M% d% m3 w& @7 z1 Z5 \ MOVS R1, #0x4         ;  //中斷#2
& W* H/ u4 z. y0 l$ c; U- ~ STR R1, [R0]          ;  //使能#2中斷/ o& p1 \3 C! @; @7 G% d4 o3 A( i. I
LDR R0, =0xE000E280   ; //設(shè)置清除中斷掛起寄存器地址5 d( t/ B& ^$ p* R( d
MOVS R1, #0x4         ;  //中斷#2
" v9 d; P$ f; Z( e! }/ F( H0 C STR R1, [R0]          ;  //清除#2的掛起狀態(tài)7 y- ]) l5 }" S  ~
}2.3 CMSIS標(biāo)準(zhǔn)設(shè)備驅(qū)動函數(shù)//設(shè)置一個(gè)中斷掛起
- k% @; \6 G8 i& e__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
# v; \" P. x8 }6 H{
' d* P4 {0 D. d1 f( K" ~) O    if ((int32_t)(IRQn) >= 0) {- D' v& }2 W. @3 C! m- Y
        NVIC->ISPR[0U] = (uint32_t)(1UL = 0) {$ V# c% N6 A7 h1 J0 b! ]: i+ Q
        NVIC->ICPR[0U] = (uint32_t)(1UL = 0) {
$ i8 ?5 M) u% [        return((uint32_t)(((NVIC->ISPR[0U] & (1UL NVIC屬于處理器內(nèi)核部分,因此在MM32 MCU芯片的用戶手冊中只有簡單的提及,沒有重點(diǎn)講述,需要深入了解相關(guān)寄存器和功能需要參考《Cortex-M0技術(shù)參考手冊》。9 d6 M) V; R8 J
' t; d; b+ E- B4 j  F. o

" S7 O+ y4 \! \& L+ b! _6 R聲明:8 n7 t$ n+ [4 Y& z* n
聲明:本號對所有原創(chuàng)、轉(zhuǎn)載文章的陳述與觀點(diǎn)均保持中立,推送文章僅供讀者學(xué)習(xí)和交流。文章、圖片等版權(quán)歸原作者享有,如有侵權(quán),聯(lián)系刪除。投稿/招聘/推廣/宣傳 請加微信:woniu26a推薦閱讀▼
& c) U( w4 ^- k2 k, M% F) m電路設(shè)計(jì)-電路分析
/ y- Q# m, Z0 ?& }emc相關(guān)文章0 a' M; U& j1 {2 s
電子元器件, V4 a6 Y% m4 ^5 p' ]. T, G5 y3 G
后臺回復(fù)“加群”,管理員拉你加入同行技術(shù)交流群。

發(fā)表回復(fù)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表