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