s3c2440-外部中斷

s3c2440 的cpu有7種中斷模式
1,user
2,fiq
3,irq
4,svc
5,abt
6,sys
7,und
一般的運行模式是user,當cpu發生什麼其他情況時,就進入對應的工作模式,比如快速中斷fiq,或者是普通中單irq。

當Without sub -register 中斷觸發之後,SRCPND相應位會被置1在沒有被INTMSK屏蔽或者不是fiq(快速中斷),
一般的中斷都屬於srcpnd模式,只有串口,can中斷屬於sub模式
當with sub -register觸發之後,subsrcpnd寄存器相應位被置1,如果沒有被intsubmsk寄存器屏蔽,他在srcpnd中也會被置1
在中斷沒有被屏蔽之後,會在intpnd寄存器中被置1,中斷服務程序可以讀取intpnd或者intoffset來判斷中斷源

中斷的優先級是在PRIORITY中進行設置,
PRIORITY的前6位表示6個次級篩選,後面的26位分別表示次級篩選器的優先級數值,
其中數值有4種情況,00,01,10,11,分別表示不同的排序,0一直在5的前面。只有1234再排序,(媽的markdown不方便上圖)

在中斷髮生之後,需要清除中斷,中斷的清除可以在中斷函數之前也可以在之後,這取決於程序的需要,不過我建議在之前,沒啥。

而中斷清除的順序也是控制好的,先清除源頭,
一般是 subsrcpnd-srcpnd-intpnd(往裏面寫1就好了)最簡單的方法是(intpnd=intpnd)
intmod可以設置fiq和irq,把相應的位置設置爲1就是設置fiq的使能,如果是irq則配置優先級(RIORITY),也可以不設置

subsrcpnd:sub模式下中斷響應寄存器,
intsubmsk:sub模式下中斷屏蔽寄存器

srcpnd:中斷響應寄存器
intmsk:中斷屏蔽寄存器,某一位別置1時,中斷被屏蔽(初始0xffffffff)
intmod:中斷類型設置寄存器,可以設置fiq(只有一個,且是置1)
intpnd:中斷標誌寄存器,可以從中讀取到中斷源
intoffset:用於表示intpnd寄存器中是那個位被置1,

又上總結具體的中斷初始化模式如下:
1,設置mode,
intmod 相應的位置1表示這個中斷是快速中斷,其餘置0,表示irq
2,更據相應的中斷設置msk
intmsk:置0表示使能,置1表示禁止,初始是0xffffff
intpubmsk:置0表示使能,置1表示禁止,初始是0xffffff
3,設置中斷優先級,
這個可以不做,採用默認模式也可以
4,編寫中斷函數,
通過關鍵之 __irq 定義中斷運行函數
5,判斷中斷源
使用intpnd或者intoffset判斷相應的中斷源。
6,發送中斷之後清除中斷
優先清除subsrcpnd(如果有)
然後是srcpnd
然後是intpnd

/*
time:2016-03-29,
change:創建文件,GPIO.c  GPIO.h
auther:wxc
*/


#include <S3C2440.H>


#define _ISR_STARTADDRESS 0x33ffff00

#define U32 unsigned int
#define pISR_EINT            (*(unsigned *)(_ISR_STARTADDRESS+0x20))



#define uint_8 unsigned char
#define uint_32 unsigned int
#define GPIO volatile unsigned long*

#define OUT 1
#define IN 0
#define false 0
#define true 1



#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
/*
功能:
參數:
返回:
*/






/*
功能:延時函數
參數:延時時間
返回:無
*/
void delay_ms(uint_32 time)
{
    int j= 5000;
    for(;time>0;time--)
    {
        for(;j>0;j--)
        ;
    }   
}

/*
功能:設置引腳方向
參數:GPx引腳類型,con 引腳方向,flag引腳值
返回:是否設置成功
*/
int GPIO_CON(GPIO GPx,int con,int flag)
{
    if(flag<0||flag>16)
    {
        return false;
    }       

    *GPx |= con<<(flag*2);
    return true;
}
/*
功能:獲取引腳值
參數:GPx引腳類型,flag引腳值
返回:返回數據
*/
int getGPIO_DAT(GPIO GPx,int flag)
{
    return (*GPx&(1<<flag))>>flag;
}


/*
功能:設置引腳值
參數:GPx引腳類型,con引腳值,flag引腳位置
返回:設置成功
*/
int setGPIO_DAT(GPIO GPx,int con,int flag)
{
    if(con>2)
    {
        return false;
    }
    if(con == OUT)
        *GPx = (*GPx|(1<<flag));
    else
        *GPx = (*GPx&~(1<<flag));      
    return true;
}
/*
功能:初始化引腳功能函數
參數:
返回:
*/
void initPin()
{
    int bool=0;
    bool = GPIO_CON(&GPBCON,OUT,5); 
    bool = GPIO_CON(&GPBCON,OUT,6);
    bool = GPIO_CON(&GPBCON,OUT,7);
    bool = GPIO_CON(&GPBCON,OUT,8); 
    GPIO_CON(&GPGCON,2,0);
    GPIO_CON(&GPGCON,2,3);
    GPIO_CON(&GPGCON,2,5);
    GPIO_CON(&GPGCON,2,6);
    GPIO_CON(&GPGCON,2,7);
    GPIO_CON(&GPGCON,2,11);


}

/*
功能:中斷函數
參數:
返回:
*/
void __irq EINT8_19()
{
    int obj=0,i=0;
    int led_array[6] = {0,3,5,6,7,11};
    /*清除中斷信號*/
    obj = INTOFFSET;
    SRCPND |= (1<<obj); //清除外部中斷8~23中斷信息       
    INTPND |= (1<<obj);
    //獲取外部中斷中斷源
    obj = EINTPEND;      
    for(i=8;i<20;i++)
    {
        if(obj &(1<<i)) //判斷這個位有沒有觸發中斷
        {                       
            setGPIO_DAT(&GPBDAT,0,7);
            EINTPEND |= 1<<i;               
        }       
    }

}
/*
功能:初始化中斷函數
參數:
返回:
*/
void initIrq()
{
    INTMSK &= ~(1<<5);     //使能8~23外部中斷   
    EINTMASK &= ~(1<<8|1<<11|1<<13|1<<14|1<<15|1<<19); //使能8 11 13 14 15 19外部中斷
    //沒有設置優先級,沒有設置fiq,沒有設置觸發模式

    pISR_EINT = (U32)EINT8_19; //設置外部中斷運行函數
}

//點個燈玩玩
int main()
{   
    int ledIndex = 5;
    int bool=0;
    initPin();
    while(1)
    {
//      GPBDAT &= ~(3<<5);
        bool = setGPIO_DAT(&GPBDAT,1,ledIndex);     
        delay_ms(10000);
        bool = setGPIO_DAT(&GPBDAT,0,ledIndex);
//      setGPIO_DAT(GPBCON,0,ledIndex);     
        delay_ms(10000);
        if(ledIndex++>8)
        {
            ledIndex = 5;
        }           
    }
    return false;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章