2440裸机编程之四 外部中断
生活随笔
收集整理的這篇文章主要介紹了
2440裸机编程之四 外部中断
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
| 2440有60個中斷源(有的中斷源還有幾個子中斷源),中斷原理如下圖: 中斷源使中斷源請求寄存器(SRCPND)的相應位置一,中斷模式寄存器(INTMOD)選擇是IRQ還是FIQ模式,如果是IRQ,在中斷屏蔽寄存器(INTMSK)不屏蔽的情況下,會產生中斷,同時中斷請求寄存器(INTPND)的相應位被置一。 2440 外部中斷?編程步驟: 外部中斷初始化() { 引腳初始化: 設置相應引腳為外部中斷功能 GPxCON ??選擇相應觸發模式? ? EXTINT 中斷初始化: 清除SRCPNF、INTPND中的相應中斷標志位 ??中斷例程地址 -> 中斷向量表 pISR_EINTx ??使能相應中斷 rINTMSK } 中斷例程()??__irq { ??……中斷程序…… ??清除SRCPNF(先)、INTPND(后)中的相應中斷標志位 } 這是一個外部中斷0的實驗程序(GPF0作外部中斷源): //******************************************************************** void Main(void) {? ??? ? ? int i; ? ? ……硬件初始化…… Eint0_init(); while(1); } void??Eint0_init(void)??//EINT0初始化 { Uart_Printf("\n外部中斷實驗:Eint0\n");? rGPFCON = rGPFCON & ~7 |??2??; //設置GPF0 為 外部中斷模式 rEXTINT0 = rEXTINT0 & ~7 | 2? ?;//設置EINT0 為 下降沿觸發 rSRCPND = 1;? ???//SRCPND寫1清0 rINTPND = 1;? ???//INTPND寫1清0 pISR_EINT0 = (U32)Eint0_ISR; //向向量表申請中斷向量 rINTMSK = rINTMSK & ~(1);??//禁止EINT0的屏蔽 } void? ?Eint0_ISR(void) __irq??//EINT0中斷例程 { Uart_Printf("你按了一次Eint0引腳的按鍵\n");? rSRCPND = 1;??//清楚EINT0中斷標志 rINTPND = 1;? } //******************************************************************* 運行結果如圖: 注意中斷標志的清除順序:SUBSRCPND(如果有)->SRCPND->INTPND??,如果不這樣做,中斷例程結束后,還會再次引起額外的中斷 注意 pISR_EINT0 = (U32)Eint0_ISR;每一個中斷例程運行之前,都要把它的地址交給中斷向量表(此指60個中斷源的eboot中斷向量表,非地址0處的異常中斷向量表,IRQ發生時,PC先指向異常中斷向量表的IRQ位置,再跳轉到eboot中斷向量表),以在中斷發生時,正確進入相應的中斷例程,其實是把INTOFFSET中的中斷號轉換成(在eboot中斷向量表的)偏移地址。 外部中斷又24個,但不都是一致的,如下圖: EINT0、EINT1、EINT2、EINT3是四個獨立的中斷源,而EINT4~7組成一個中斷源,EINT8~23組成一個中斷源。 那么EINT4~7的中斷程序如何寫,顯然不能用EINT0的方式,不然EINT4~EINT7的四個源相互之間無法被區分開,EINT8~23也同理。 所以為了區分它們,要用到EINTMASK和EINTPEND,EINTMASK每一位對應EINT4~EINT23的屏蔽,其他位保留;EINTPEND每一位對應EINT4~EINT23的中斷請求,其他位保留;這樣就可以順利區分EINT4~EINT23了。 下面是Eint2和Eint11的中斷程序 //******************************************************************** void Main(void) {? ??? ? ? int i; ? ? ……硬件初始化…… Uart_Printf("\n外部中斷實驗:Eint2 和 Eint8_23\n"); Eint2_init(); Eint8_23_init(); //EINT11初始化 while(1); } void??Eint2_init(void)??//EINT2初始化 { rGPFCON = rGPFCON & ~3<<4 |??2<<4??; //設置GPF2 為 外部中斷模式 rEXTINT0 = rEXTINT0 & ~7<<8 | 4<<8? ?;//設置EINT2 為 上升沿觸發 rSRCPND = 1<<2;? ???//SRCPND寫1清0 rINTPND = 1<<2;? ???//INTPND寫1清0 pISR_EINT2 = (U32)Eint2_ISR;??//填入Eint2的中斷向量 rINTMSK = rINTMSK & ~(1<<2);??//禁止EINT2的屏蔽 } void? ?Eint2_ISR(void) __irq??//EINT2中斷例程 { Uart_Printf("你按了一次Eint2引腳的按鍵\n");? rSRCPND = 1<<2;??//清楚EINT2中斷標志 rINTPND = 1<<2; } void??Eint8_23_init(void)??//Eint8_23初始化 { rGPGCON = rGPGCON & ~3<<6 |??2<<6??; //設置GPG3 為 外部中斷模式 rEXTINT1 = rEXTINT1 & ~7<<12 | 2<<12? ?;//設置EINT11 為 下降沿觸發 rEINTPEND = 1<<11;? ? //***EINTPEND中的 EINT11位 清0 rSRCPND = 1<<5;? ???//SRCPND中的 Eint8_23位 清0 rINTPND = 1<<5;? ???//INTPND中的 Eint8_23位 清0 pISR_EINT8_23 = (U32)Eint8_23_ISR;??//填入Eint8_23的中斷向量 rEINTMASK = rEINTMASK & ~(1<<11);??//***禁止EINT11的屏蔽 rINTMSK = rINTMSK & ~(1<<5);??//禁止Eint8_23的屏蔽 } void? ?Eint8_23_ISR(void) __irq??//EINT2中斷例程 { Uart_Printf("你按了一次Eint8_23引腳的按鍵\n"); rEINTPEND = 1<<11;? ? //***EINTPEND中的 EINT11位 清0 rSRCPND = 1<<5;? ???//SRCPND中的 Eint8_23位 清0 rINTPND = 1<<5;? ???//INTPND中的 Eint8_23位 清0 } //******************************************************************* 結果如下: |
總結
以上是生活随笔為你收集整理的2440裸机编程之四 外部中断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux驱动模型开发——linux p
- 下一篇: TQ210裸机编程(4)——按键(中断法