這篇文章主要講解了“arm9中斷結(jié)構(gòu)是怎樣的”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“arm9中斷結(jié)構(gòu)是怎樣的”吧!
創(chuàng)新互聯(lián)專(zhuān)注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、墨竹工卡網(wǎng)絡(luò)推廣、微信小程序定制開(kāi)發(fā)、墨竹工卡網(wǎng)絡(luò)營(yíng)銷(xiāo)、墨竹工卡企業(yè)策劃、墨竹工卡品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供墨竹工卡建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:bm7419.com
S3C2440的中斷分為兩大類(lèi): 外部中斷 和 內(nèi)部中斷.
EXTINT[x]: 用來(lái)配置各個(gè)引腳的中斷觸發(fā)方式 (高電平觸發(fā)、低電平觸發(fā)、下降沿觸發(fā)、上升沿觸發(fā)), 注意該寄存器與中斷源的對(duì)應(yīng)關(guān)系
EINTPEND[x]: xxxPEND的寄存器都是狀態(tài)寄存器, 初始化時(shí)先清除標(biāo)志, 在清除中斷的時(shí)候?qū)⒓拇嫫鞯闹蒂x值給本身即可
EINTMSK[x]: 1 屏蔽中斷; 0 未屏蔽
SRCPEND[x]: 1 申請(qǐng)中斷; 0 未申請(qǐng)中斷
EINTFLT0~EINTFLT3: 配置濾波時(shí)鐘和濾波寬度
INTMOD[x]: 1: FIQ, 0: IRQ
內(nèi)部中斷分兩種: 帶子中斷的中斷 和 不帶子中斷的中斷
不帶子中斷: 發(fā)生中斷后 SRCPEND置位, 如果沒(méi)有被 INTMSK屏蔽, 那么繼續(xù)向下一步申請(qǐng)中斷
帶子中斷: 發(fā)生中斷之后, 先將 SUBSRCPEND 置位, 如果沒(méi)有INTSUBMSK屏蔽則向 SRCPEND申請(qǐng)中斷. 如果沒(méi)有被INTMSK屏蔽則進(jìn)一步向下申請(qǐng)中斷
中斷的優(yōu)先級(jí):
ARB_MODEx: 控制中斷優(yōu)先級(jí)是否輪轉(zhuǎn)
ARB_SELx: 控制輪轉(zhuǎn)順序
中斷的開(kāi)啟(xxxMSK):
1 外部中斷: EINT4~23先初始化EINTMSK 和 INTMSK, 如果是EINT0~3直接初始化INTMSK
2 內(nèi)部中斷: 有子中斷先初始化 INTSUBMSK 再初始化 INTMSK, 如果是不帶子中斷的內(nèi)部中斷直接初始化 INTMSK
中斷的清除(xxxPEND):
1 外部中斷: 如果是EINT4~23 先清除EINTPEND 再清除 INTPEND (注意順序), 如果是 EINT0~3 直接清除SRCPEND. (不需要清除 INTPEND???)
2 內(nèi)部中斷: 帶子中斷, 先清除 SUBSRCPEND再清除SRCPEND(注意順序); 不帶子中斷直接清除SRCPEND
3 清除中斷是寫(xiě) 1 清除
@****************************************************************************** @ File:head.S @ 功能:初始化,設(shè)置中斷模式、管理模式的棧,設(shè)置好中斷處理函數(shù) @****************************************************************************** .extern main .text .global _start _start: @****************************************************************************** @ 中斷向量,本程序中,除Reset和HandleIRQ外,其它異常都沒(méi)有使用 @****************************************************************************** b Reset @ 0x04: 未定義指令中止模式的向量地址 HandleUndef: b HandleUndef @ 0x08: 管理模式的向量地址,通過(guò)SWI指令進(jìn)入此模式 HandleSWI: b HandleSWI @ 0x0c: 指令預(yù)取終止導(dǎo)致的異常的向量地址 HandlePrefetchAbort: b HandlePrefetchAbort @ 0x10: 數(shù)據(jù)訪問(wèn)終止導(dǎo)致的異常的向量地址 HandleDataAbort: b HandleDataAbort @ 0x14: 保留 HandleNotUsed: b HandleNotUsed @ 0x18: 中斷模式的向量地址 注意這里由下邊實(shí)現(xiàn) b HandleIRQ @ 0x1c: 快中斷模式的向量地址 HandleFIQ: b HandleFIQ Reset: ldr sp, =4096 @ 設(shè)置棧指針,以下都是C函數(shù),調(diào)用前需要設(shè)好棧 bl disable_watch_dog @ 關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟 msr cpsr_c, #0xd2 @ 進(jìn)入中斷模式 ldr sp, =3072 @ 設(shè)置中斷模式棧指針 msr cpsr_c, #0xd3 @ 進(jìn)入管理模式, reset之后就是管理模式, 所以這里的設(shè)置和reset下的ldr sp, =4096為一個(gè)作用, 本條代碼可以省略 ldr sp, =4096 @ 設(shè)置管理模式棧指針, @ 其實(shí)復(fù)位之后,CPU就處于管理模式, @ 前面的“l(fā)dr sp, =4096”完成同樣的功能,此句可省略 bl init_led @ 初始化LED的GPIO管腳 bl init_irq @ 調(diào)用中斷初始化函數(shù),在init.c中 msr cpsr_c, #0x5f @ 設(shè)置I-bit=0,開(kāi)IRQ中斷 ldr lr, =halt_loop @ 設(shè)置返回地址 ldr pc, =main @ 調(diào)用main函數(shù) halt_loop: b halt_loop HandleIRQ: sub lr, lr, #4 @ 計(jì)算返回地址 stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器 @ 注意,此時(shí)的sp是中斷模式的sp @ 初始值是上面設(shè)置的3072 ldr lr, =int_return @ 設(shè)置調(diào)用ISR即EINT_Handle函數(shù)后的返回地址 ldr pc, =EINT_Handle @ 調(diào)用中斷服務(wù)函數(shù),在interrupt.c中 int_return: ldmia sp!, { r0-r12,pc }^ @ 中斷返回, ^表示將spsr的值復(fù)制到cpsr
注意: 1. 這里中斷并不是根據(jù)名字來(lái)確定的, 而是根據(jù)中斷向量的地址(0x0 / 0x4 / 0x8 / 0xc / 0x10...). IRQ正是0x18. 只需要在該位置放置一條跳轉(zhuǎn)指令即可實(shí)現(xiàn)中斷isr. 這是只要是IRQ都要從這一個(gè)入口進(jìn)入中斷, 然后再檢查到底是哪個(gè)源申請(qǐng)了中斷.
芯片在各個(gè)模式之下使用的是不同的sp和lr寄存器, reset之后就是管理模式, 所以管理模式的ldr sp, =4096是等價(jià)于reset下的那條sp語(yǔ)句
// init.c: 初始化LED及 中斷 #include "s3c24xx.h" // LED1,LED2,LED4對(duì)應(yīng)GPF4、GPF5、GPF6 #define GPF4_out (1<<(4*2)) #define GPF5_out (1<<(5*2)) #define GPF6_out (1<<(6*2)) #define GPF4_msk (3<<(4*2)) #define GPF5_msk (3<<(5*2)) #define GPF6_msk (3<<(6*2)) /* * S2,S3,S4對(duì)應(yīng)GPF0、GPF2、GPG3 */ #define GPF0_eint (0x2<<(0*2)) #define GPF2_eint (0x2<<(2*2)) #define GPG3_eint (0x2<<(3*2)) #define GPF0_msk (3<<(0*2)) #define GPF2_msk (3<<(2*2)) #define GPG3_msk (3<<(3*2)) // 關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟 void disable_watch_dog(void) { WTCON = 0; // 關(guān)閉WATCHDOG很簡(jiǎn)單,往這個(gè)寄存器寫(xiě)0即可 } void init_led(void) { // LED1,LED2,LED4對(duì)應(yīng)的3根引腳設(shè)為輸出 GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk); GPFCON |= GPF4_out | GPF5_out | GPF6_out; } /* 初始化GPIO引腳為外部中斷 * GPIO引腳用作外部中斷時(shí),默認(rèn)為低電平觸發(fā)、IRQ方式(不用設(shè)置INTMOD) */ void init_irq( ) { // S2,S3對(duì)應(yīng)的2根引腳設(shè)為中斷引腳 EINT0,ENT2 GPFCON &= ~(GPF0_msk | GPF2_msk); GPFCON |= GPF0_eint | GPF2_eint; // S4對(duì)應(yīng)的引腳設(shè)為中斷引腳EINT11 GPGCON &= ~GPG3_msk; GPGCON |= GPG3_eint; // 對(duì)于EINT11,需要在EINTMASK寄存器中使能它 EINTMASK &= ~(1<<11); /* * 設(shè)定優(yōu)先級(jí): * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2 * 仲裁器1、6無(wú)需設(shè)置 * 最終: * EINT0 > EINT2 > EINT11即K2 > K3 > K4 */ PRIORITY &= ((((~0x01) | (0x3<<7))) | (0x0 << 7)) ; // EINT0、EINT2、EINT8_23使能 INTMSK &= (~(1<<0)) & (~(1<<2)) & (~(1<<5)); }
中斷初始化步驟:
(1) 設(shè)置好 IRQ 和 FIQ 的棧
(2) 準(zhǔn)備中斷處理函數(shù)
1. 異常向量中設(shè)置好跳轉(zhuǎn)函數(shù)
2. 中斷服務(wù)程序(ISR)
3. 清除中斷
4. 保護(hù)現(xiàn)場(chǎng), 恢復(fù)現(xiàn)場(chǎng)
(3) 根據(jù)中斷源設(shè)置相關(guān)外設(shè)
外部中斷: 設(shè)置引腳為"外部中斷", 設(shè)置中斷觸發(fā)方式, 開(kāi)啟對(duì)應(yīng)的屏蔽寄存器, EINTMSK
內(nèi)部中斷: 將INTSUBMSK開(kāi)啟
(4)確定中斷的使用方式: IRQ 或 FIQ
FIQ: 在 INTMOD 設(shè)置相應(yīng)的bit為1
IRQ: 在PRIORITY寄存器中設(shè)置優(yōu)先級(jí), 將 INTMSK中設(shè)置為0 (FIQ不受INTMSK影響)
(5) 置位 CPSR中的 I-bit(IRQ) 或 F-bit(FIQ)
#include "s3c24xx.h" void EINT_Handle() { unsigned long oft = INTOFFSET;//INTPND[X]為1,則INTOFFSET為x unsigned long val; switch( oft ) { // S2被按下 case 0: { GPFDAT |= (0x7<<4); // 所有LED熄滅 GPFDAT &= ~(1<<4); // LED1點(diǎn)亮 break; } // S3被按下 case 2: { GPFDAT |= (0x7<<4); // 所有LED熄滅 GPFDAT &= ~(1<<5); // LED2點(diǎn)亮 break; } // K4被按下 case 5: { GPFDAT |= (0x7<<4); // 所有LED熄滅 GPFDAT &= ~(1<<6); // LED4點(diǎn)亮 break; } //K1 或 K2 被按下, 假設(shè)K1 k2 接在EINT8~23, 查詢INTPEND[5]之后還要查詢EINTPEND[x]來(lái)確定EINT8~EINT23 case 5: { GPBDAT |= (0x0f << 5);//所有LED熄滅 //需要進(jìn)一步判斷是k1 還是 k2, 或是 同時(shí)按下 val = EINTPEND; if (val & (1 << 11)) { GPBDAT &= ~(1 << 6);//K2 } if (val & (1 << 19)) { GPBDAT &= ~(1 << 5);//K1 } break; } default: break; } //清中斷 if( oft == 5 ) //如果是外部中斷則要多清除EINTPEND這個(gè)寄存器 EINTPEND = (1<<11); // EINT8_23合用IRQ5,SRCPND[5], INTPND[5] SRCPND = 1<<oft; INTPND = 1<<oft; }
這里oft表示INTOFFSET寄存器的值, INTPND[x]為1, oft就是x. 該值為5表示 EINT8-23的中斷源, 這時(shí)再查看 EINTPEND來(lái)確定到底是哪個(gè)引腳.
感謝各位的閱讀,以上就是“arm9中斷結(jié)構(gòu)是怎樣的”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)arm9中斷結(jié)構(gòu)是怎樣的這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
網(wǎng)頁(yè)題目:arm9中斷結(jié)構(gòu)是怎樣的
文章轉(zhuǎn)載:http://bm7419.com/article34/iiopse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、云服務(wù)器、做網(wǎng)站、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、App開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)