歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 嵌入式學習之ARM中斷編程

嵌入式學習之ARM中斷編程

日期:2017/3/1 9:55:52   编辑:Linux編程

一、中斷控制寄存器

ARM微處理器支持7種工作模式,分別為:

1. 用戶模式(Usr) 用於正常執行程序

2. 快速中斷模式(FIQ) 用於高速數據傳輸

3. 外部中斷模式(IRQ) 用於通常的中斷處理

4. 管理模式(SVC) 操作系統使用的保護模式(高權限),復位和軟件中斷進入

5. 數據訪問終止模式(abt) 當數據或指令預取終止時進入該模式,可用於虛擬內存及存儲保護

6. 系統模式(sys) 運行均有特權的操作系統任務

7. 未定義指令終止模式(und) 用於支持硬件協處理器的軟件仿真(浮點、微量運算)

通過軟件編程可以實現各個模式之間進行切換,各個模式所占的寄存器如下圖所示:

每種中斷模式除了共同的寄存器R0~R15這16個寄存器之外,還包括CPSR即當前程序狀態寄存器(current programe status register),CPSR中的各個位用於指明當前程序所處的中斷狀態和模式,寄存器的各位作用如下:

M0~M4用於表示程序當前工作的中斷模式,對應於如下各個工作模式:

T位用於指定當前CPU是出去Thumb(16位)還是處於ARM(32位)狀態;

N位:N=1表示運算的結果為負數;N=0 表示運算的結果為正數或零;

Z 位:Z=1 表示運算的結果為零;Z=0表示運算的結果為非零;

C位:進位、借位標記位:當運算結果產生了進位時(無符號數溢出),C=1,否則C=0。

二、中斷控制編程:

通過對中斷控制寄存器中的各位進行編程控制可以實現中斷,各控制位參見http://www.linuxidc.com/Linux/2013-06/86133.htm,下面主要介紹他們的編程實現。

void init_irq( )
{
// S2,S3對應的2根引腳設為中斷引腳 EINT0,ENT2
GPFCON &= ~(GPF0_msk | GPF2_msk);
GPFCON |= GPF0_eint | GPF2_eint;

// S4對應的引腳設為中斷引腳EINT11
GPGCON &= ~GPG3_msk;
GPGCON |= GPG3_eint;

// 對於EINT11,需要在EINTMASK寄存器中使能它
EINTMASK &= ~(1<<11);

/*
* 設定優先級:
* ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2
* 仲裁器1、6無需設置
* 最終:
* EINT0 > EINT2 > EINT11即K2 > K3 > K4
*/
PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;

// EINT0、EINT2、EINT8_23使能
INTMSK &= (~(1<<0)) & (~(1<<2)) & (~(1<<5));
}

void int_init(void)
{
rSRCPND = rSRCPND; // clear all interrupt
rINTPND = rINTPND; // clear all interrupt

// nIntMode='3';
rGPFCON = (rGPFCON & 0xffcc) | (1<<5) | (1<<1); // PF0/2 = EINT0/2
rGPGCON = (rGPGCON & 0xff3fff3f) | (1<<23) | (1<<7); // PG3/11 = EINT11/19

pISR_EINT0=(UINT32T)isrEINT0;//int0_int; //isrEINT0;
pISR_EINT8_23=(UINT32T)isrEINT11_19;//int11_int; //isrEINT11_19;

rEINTPEND = 0xffffff;
rSRCPND = BIT_EINT0 | BIT_EINT8_23; //to clear the previous pending states
rINTPND = BIT_EINT0 | BIT_EINT8_23;

rEXTINT0 = (rEXTINT0 & ~((7<<8) | (0x7<<0))) | 0x2<<8 | 0x2<<0; // EINT0/2=falling edge triggered
rEXTINT1 = (rEXTINT1 & ~(7<<12)) | 0x2<<12; //EINT11=falling edge triggered

rEINTMASK &= ~(1<<11);
rINTMSK &= ~(BIT_EINT0 | BIT_EINT8_23);
}

Copyright © Linux教程網 All Rights Reserved