在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > S3C2440外部中斷詳解

            S3C2440外部中斷詳解

            作者: 時間:2016-12-02 來源:網絡 收藏
            要想正確地執(zhí)行2440的外部中斷,一般需要完成兩個部分內容:中斷初始化和中斷處理函數。
            在具體執(zhí)行中斷之前,要初始化好要用的中斷。2440的外部中斷引腳EINT與通用IO引腳F和G復用,要想使用中斷功能,就要把相應的引腳配置成中斷模式,如我們想把端口F0設置成外部中斷,而其他引腳功能不變,則GPFCON=(GPFCON & ~0x3) | 0x2。配置完引腳后,還需要配置具體的中斷功能。我們要打開某一中斷的屏蔽,這樣才能響應該中斷,相對應的寄存器為INTMSK;還要設置外部中斷的觸發(fā)方式,如低電平、高電平、上升沿、下降沿等,相對應的寄存器為EXTINTn。另外由于EINT4到EINT7共用一個中斷向量,EINT8到EINT23也共用一個中斷向量,而INTMSK只負責總的中斷向量的屏蔽,要具體打開某一具體的中斷屏蔽,還需要設置EINTMASK。上面介紹的是最基本的初始化,當然還有一些其他的配置,如當需要用到快速中斷時,要使用INTMOD,當需要配置中斷優(yōu)先級時,要使用PRIORITY等。
            中斷處理函數負責執(zhí)行具體的中斷指令,除此以外還需要把SRCPND和INTPND中的相應的位清零(通過置1來清零),因為當中斷發(fā)生時,2440會自動把這兩個寄存器中相對應的位置1,以表示某一中斷發(fā)生,如果不在中斷處理函數內把它們清零,系統(tǒng)會一直執(zhí)行該中斷函數。另外還是由于前面介紹過的,有一些中斷是共用一個中斷向量的,而一個中斷向量只能有一個中斷執(zhí)行函數,因此具體是哪個外部中斷,還需要EINTPEND來判斷,并同樣還要通過置1的方式把相應的位清零。一般來說,使用__irq這個關鍵詞來定義中斷處理函數,這樣系統(tǒng)會為我們自動保存一些必要的變量,并能夠在中斷處理函數執(zhí)行完后正確地返回。還需要注意的是,中斷處理函數不能有返回值,也不能傳遞任何參數。
            為了把這個中斷處理函數與在2440啟動文件中定義的中斷向量表相對應上,需要先定義中斷入口地址變量,該中斷入口地址必須與中斷向量表中的地址一致,然后把該中斷處理函數的首地址傳遞給該變量,即中斷入口地址。
            下面就是一個外部中斷的實例。開發(fā)板上一共有四個按鍵,分別連到了EINT0,EINT1,EINT2和EINT4,我們讓這四個按鍵分別控制連接在B5~B8引腳上的四個LED:按一下鍵則LED亮,再按一下則滅:
            #define _ISR_STARTADDRESS 0x33ffff00
            #define U32 unsigned int
            #define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
            #define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))
            #define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28))
            #define pISR_EINT4_7 (*(unsigned *)(_ISR_STARTADDRESS+0x30))
            #define rSRCPND (*(volatile unsigned *)0x4a000000) //Interrupt request status
            #define rINTMSK (*(volatile unsigned *)0x4a000008) //Interrupt mask control
            #define rINTPND (*(volatile unsigned *)0x4a000010) //Interrupt request status
            #define rGPBCON (*(volatile unsigned *)0x56000010) //Port B control
            #define rGPBDAT (*(volatile unsigned *)0x56000014) //Port B data
            #define rGPBUP (*(volatile unsigned *)0x56000018) //Pull-up control B
            #define rGPFCON (*(volatile unsigned *)0x56000050) //Port F control
            #define rEXTINT0 (*(volatile unsigned *)0x56000088) //External interrupt control register 0
            #define rEINTMASK (*(volatile unsigned *)0x560000a4) //External interrupt mask
            #define rEINTPEND (*(volatile unsigned *)0x560000a8) //External interrupt pending
            static void __irq Key1_ISR(void) //EINT1
            {
            int led;
            rSRCPND = rSRCPND | (0x1<<1);
            rINTPND = rINTPND | (0x1<<1);
            led = rGPBDAT & (0x1<<5);
            if (led ==0)
            rGPBDAT = rGPBDAT | (0x1<<5);
            else
            rGPBDAT = rGPBDAT & ~(0x1<<5);
            }
            static void __irq Key2_ISR(void) //EINT4
            {
            int led;
            rSRCPND = rSRCPND | (0x1<<4);
            rINTPND = rINTPND | (0x1<<4);
            if(rEINTPEND&(1<<4))
            {
            rEINTPEND = rEINTPEND | (0x1<<4);
            led = rGPBDAT & (0x1<<6);
            if (led ==0)
            rGPBDAT = rGPBDAT | (0x1<<6);
            else
            rGPBDAT = rGPBDAT & ~(0x1<<6);
            }
            }
            static void __irq Key3_ISR(void) //EINT2
            {
            int led;
            rSRCPND = rSRCPND | (0x1<<2);
            rINTPND = rINTPND | (0x1<<2);
            led = rGPBDAT & (0x1<<7);
            if (led ==0)
            rGPBDAT = rGPBDAT | (0x1<<7);
            else
            rGPBDAT = rGPBDAT & ~(0x1<<7);
            }
            void __irq Key4_ISR(void) //EINT0
            {
            int led;
            rSRCPND = rSRCPND | 0x1;
            rINTPND = rINTPND | 0x1;
            led = rGPBDAT & (0x1<<8);
            if (led ==0)
            rGPBDAT = rGPBDAT | (0x1<<8);
            else
            rGPBDAT = rGPBDAT & ~(0x1<<8);
            }
            void Main(void)
            {
            int light;
            rGPBCON = 0x015550;
            rGPBUP = 0x7ff;
            rGPFCON = 0xaaaa;
            rSRCPND = 0x17;
            rINTMSK = ~0x17;
            rINTPND =0x17;
            rEINTPEND = (1<<4);
            rEINTMASK = ~(1<<4);
            rEXTINT0 = 0x20222;
            light = 0x0;
            rGPBDAT = ~light;
            pISR_EINT0 = (U32)Key4_ISR;
            pISR_EINT1 = (U32)Key1_ISR;
            pISR_EINT2 = (U32)Key3_ISR;
            pISR_EINT4_7 = (U32)Key2_ISR;
            while(1)
            ;
            }
            /******************************************************************************************************************************************************************************************************/

            1.中斷分兩大類:內部中斷和外部中斷。

            本文引用地址:http://www.biyoush.com/article/201612/325056.htm

            2.外部中斷。24個外部中斷占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。用這些腳做中斷輸入,則必須配置引腳為中斷,并且不要上拉。具體參考datesheet數據手冊。

            寄存器:EXTINT0-EXTINT2:三個寄存器設定EINT0-EINT23的觸發(fā)方式。

            EINTFLT0-EINTFLT3:控制濾波時鐘和濾波寬度。

            EINTPEND:這個是中斷掛起寄存器,清除時要寫1,后面還有幾個是寫1清除。當一個外部中斷(EINT4-EINT23)發(fā)生后,那么相應的位會被置1。為什么沒有EINT0-EINT3,呵呵,看看SRCPND就知道了,里面沒有EINT4-EINT23的位子(SRCPND第[3]位為EINT4-7組,第[4]位為EINT8-23組),所以有了EINTPENDx用以細化補充SRCPND。

            EINTMASK:這個簡單,是屏蔽中斷用的,也就是說位為1時,此次中斷無效。

            3.內部中斷。內部中斷有8個寄存器,下面逐一來看。

            寄存器:SUBSRCPND:當一個中斷發(fā)生后,那么相應的位會被置1,表示一個中斷發(fā)生了。

            INTSUBMSK:與上一個是一伙的,中斷屏蔽寄存器,具體屏蔽什么,自己看手冊去吧。

            INTMOD:中斷的方式。一個中斷可以是普通中斷,也可以是快中斷,在這里設置,但只能有一個快中斷。

            PRIORITY:優(yōu)先級寄存器,不說了。

            SRCPND:當一個中斷發(fā)生后,那么相應的位會被置1,表示一個或一類中斷發(fā)生了。

            INTMSK:中斷屏蔽寄存器。

            INTPND:中斷發(fā)生后,SRCPND中會有位置1,可能好幾個(因為同時可能發(fā)生幾個中斷),這些中斷會由優(yōu)先級仲裁器選出一個最緊迫的,然后把INTPND中相應位置1,所以同一時間只有一位是1。也就是說前面的寄存器置1是表示發(fā)生了,只有INTPND置1,CPU才會處理。

            INTOFFSET:用來表示INTPND中哪一位置1了,好讓你查詢,普通中斷跳轉時查詢用。清除INTPND、SRCPND時自動清除。

            4.各寄存器關系:

            下面看圖說明:

            5.中斷過程。

            a如果是不帶子中斷的內部中斷:發(fā)生后SRCPND相應位置1,如果沒有被INTMSK屏蔽,那么等待進一步處理。

            b如果是帶子中斷的內部中斷:發(fā)生后SUBSRCPND相應位置1,如果沒有被INTSUBMSK屏蔽,那么SRCPND相應位置1,等待進一步處理,幾個SUBSRCPND可能對應同一個SRCPND,對應表如下:

            SRCPND SUBSRCPND
            INT_UART0 INT_RXD0,INT_TXD0,INT_ERR0
            INT_UART1 INT_RXD1,INT_TXD1,INT_ERR1
            INT_UART2 INT_RXD2,INT_TXD2,INT_ERR2
            INT_ADC INT_ADC_S, INT_TC
            INT_CAM INT_CAM_C, INT_CAM_P
            INT_WDT_AC97 INT_WDT, INT_AC97

            c如果是外部中斷:EINT0-EINT3發(fā)生后SRCPND相應位置1,如果沒有被INTMSK屏蔽,那么等待進一步處理。EINT4-EINT23發(fā)生后EINTPEND相應位置1,如果沒有被EINTMASK屏蔽,那么SRCPND相應位EINT4-7或EINT8-23置1,如果沒有被INTMSK屏蔽,等待進一步處理。幾個EINTPEND對應同一個SRCPND,對應表如下:

            SRCPND EINTPEND

            EINT0 EINT0

            EINT1 EINT1

            EINT2 EINT2

            EINT3 EINT3

            EINT4-7 EINT4 EINT5EINT6EINT7

            EINT8-23 EINT8 EINT9EINT10EINT11……EINT23

            三種中斷都等待進一步處理了。接下來從SRCPND往下看,看INTMSK。如果中斷被屏蔽了,就不用說了。如果沒有被屏蔽,那么會進一步到INTMOD。如果是快中斷,那么直接出來,進入FIQ(即CPU進入快中斷模式處理)。如果是普通中斷,那么SRCPND可以有多位為置1(FIQ只能有一個),這時就會經過PRIORITY選出一個優(yōu)先級高的,然后把根據選出的中斷把INTPND相應位置1(注意:只能選出一個),進入IRQ,讓CPU處理。

            6.中斷的開啟。

            a.如果是不帶子中斷的內部中斷,只需設置INTMSK,讓它不屏蔽中斷就可以了。

            b如果是帶子中斷的內部中斷,需設置INTSUBMSK和INTMSK,讓它們不屏蔽中斷就可以了。

            c如果是外部中斷,對于EINT8-23需要設置EINTMASK和INTMSK。對于EINT0-EINT3只需設置INTMSK。

            7.中斷的清除。

            a.如果是不帶子中斷的內部中斷,只需清除SRCPND,注意清除需位置1。

            b如果是帶子中斷的內部中斷,需清除SRCPND和SUBSRCPND,注意先清除SUBSRCPND,再清除SRCPND。因為,如果你先清除SRCPND的話,然后在清除SUBSRCPND的過程中,SRCPND會以為又有中斷發(fā)生,又會置1。也就是說一次中斷會響應兩次。所以必須先掐斷源頭。

            c如果是外部中斷,對于EINT8-23需要清除EINTPEND和SRCPND(同樣注意順序)。對于EINT0-EINT3只需清除SRCPND。

            本文詳細分析了S3C2440的中斷寄存器,對arm初學者有一定的幫助。




            關鍵詞: S3C2440外部中

            評論


            技術專區(qū)

            關閉