色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 裸奔程序之外部中斷檢測(cè)按鍵

          裸奔程序之外部中斷檢測(cè)按鍵

          作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò) 收藏
          開(kāi)發(fā)環(huán)境:ADS1.2

          實(shí)驗(yàn)實(shí)驗(yàn)功能:在TQ2440開(kāi)發(fā)板上,利用外部中斷模式檢測(cè)按鍵是否按下,

          本文引用地址:http://cafeforensic.com/article/201611/318703.htm

          如果某按鍵被按下則點(diǎn)亮對(duì)應(yīng)某個(gè)LED。

          ——————————————————————————————————

          #include"2440addr.h"
          #include"option.h" //這個(gè)文件中定義了中斷服務(wù)程序的起始地址


          #define LED1_ON (rGPBDAT &=~(1<<5))
          #define LED1_OFF (rGPBDAT |=(1<<5) )
          #define LED2_ON (rGPBDAT &=~(1<<6))
          #define LED2_OFF (rGPBDAT |=(1<<6))
          #define LED3_ON (rGPBDAT &=~(1<<7))
          #define LED3_OFF (rGPBDAT |=(1<<7))
          #define LED4_ON (rGPBDAT &=~(1<<8))
          #define LED4_OFF (rGPBDAT |=(1<<8))

          void Delay(void)
          {
          int i;
          for(i=0;i<100000;i++);
          }


          /外部中斷處理函數(shù)/

          void __irq IRQ_KEY1(void)
          {

          rSRCPND |=(1<<1); //清除中斷標(biāo)志位
          rINTPND |=(1<<1);

          LED1_ON;
          Delay();
          LED1_OFF;
          }

          void __irq IRQ_KEY2(void)
          {

          rSRCPND |=(1<<4); //清除中斷標(biāo)志位
          rINTPND |=(1<<4);
          rEINTPEND |=(1<<4); //清除ENIT4的中斷標(biāo)志位

          LED2_ON;
          Delay();
          LED2_OFF;
          }

          void __irq IRQ_KEY3(void)
          {
          rSRCPND |=(1<<2); //清除中斷標(biāo)志位
          rINTPND |=(1<<2);

          LED3_ON;
          Delay();
          LED3_OFF;
          }

          void __irq IRQ_KEY4(void)
          {

          rSRCPND |=1<<0; //清除中斷標(biāo)志位
          rINTPND |=1<<0;

          LED4_ON;
          Delay();
          LED4_OFF;
          }
          /外部中斷初始化函數(shù)/
          void Eint_Init(void)
          {
          rGPFCON &=~(0x33f);
          rGPFCON |=0x22a; //設(shè)置GPF0、1、2、4為中斷輸入功能

          rEXTINT0 = 0x20222; //ENIT0、1、2、4下降沿觸發(fā)中斷

          rSRCPND = 0x17; //清除ENIT0、1、2、4的中斷標(biāo)志位
          rINTPND = 0x17; //清除ENIT0、1、2、4的中斷標(biāo)志位
          rEINTPEND=(1<<4); //清除ENIT4的中斷標(biāo)志位

          rINTMOD=0x0; //所有中斷為IRQ中斷

          rINTMSK &= ~0x17; //ENIT0、1、2、4中斷服務(wù)有效(這里就是使能外部中斷)
          rEINTMASK &= ~(1<<4); //EINT4中斷服務(wù)有效


          pISR_EINT0 = (unsigned)IRQ_KEY4; //設(shè)置各中斷服務(wù)子程序地址
          pISR_EINT1 = (unsigned)IRQ_KEY1;
          pISR_EINT2 = (unsigned)IRQ_KEY3;
          pISR_EINT4_7 = (unsigned)IRQ_KEY2;
          }

          void Main(void)
          {
          rGPBCON &=~((3<<10)|(3<<12)|(3<<14)|(3<<16)); //對(duì)GPBCON[10:17]清零
          rGPBCON |=((1<<10)|(1<<12)|(1<<14)|(1<<16)); //設(shè)置GPB5~8為輸出
          rGPBUP &=~((1<<5)|(1<<6)|(1<<7)|(1<<8)); //設(shè)置GPB5~8的上拉功能
          rGPBDAT |=(1<<5)|(1<<6)|(1<<7)|(1<<8); //關(guān)閉LED

          Eint_Init();
          while(1);
          }

          ——————————————————————————————————

          我們來(lái)簡(jiǎn)單描述一下S3C2440的中斷內(nèi)容,它總共有60個(gè)中斷源,分為中斷源和子中斷源;下圖為中斷源種類:


          下圖為子中斷源種類:

          中斷控制器所用到的中斷寄存器有八個(gè):

          中斷處理框圖如下所示(重點(diǎn)):

          現(xiàn)在主要說(shuō)下外部中斷(其寄存器使用說(shuō)明在數(shù)據(jù)手冊(cè)的輸入輸出端口章節(jié))

          S3C2440有24個(gè)外部中斷,GPF0--GPF7對(duì)應(yīng)于外部中斷EINT0--EINT7,GPG0--GPG15對(duì)應(yīng)于外部中斷EINT8--EINT23,支持上升沿、下降沿、高電平、低電平、雙邊沿觸發(fā)。

          設(shè)置外部中斷的一般步驟

          1、選擇管腳功能為外部中斷功能
          2、設(shè)置觸發(fā)方式
          3、清中斷源掛起寄存器,中斷服務(wù)寄存器(可選,防止原有中斷干擾)
          4、設(shè)置中斷模式(IRQ、FRQ, 默認(rèn)為IRQ)
          5、設(shè)置中斷優(yōu)先級(jí)(可選,一般默認(rèn))
          6、打開(kāi)外部中斷屏蔽
          7、設(shè)置中斷服務(wù)入口程序

          下面我們開(kāi)始分析main.c這個(gè)程序,首先從main函數(shù)開(kāi)始;

          進(jìn)入main函數(shù)后,首先是初始化LED,這四條語(yǔ)句在前面LED已經(jīng)講過(guò),這里不再重復(fù);接著調(diào)用Eint_Init();我們進(jìn)入Eint_Init();函數(shù)看到,

          首先是 rGPFCON &=~(0x33f); rGPFCON |=0x22a; 執(zhí)行完這二句后,GPF0、1、2、4被設(shè)置為中斷輸入功能。

          接著執(zhí)行rEXTINT0 = 0x20222; 意思是將ENIT0、1、2、4配置為下降沿觸發(fā)中斷。

          再執(zhí)行rSRCPND = 0x17; 意思是清除ENIT0、1、2、4的中斷標(biāo)志位,SRCPND這個(gè)寄存器是中斷請(qǐng)求標(biāo)識(shí)的寄存器,如果SRCPND中哪一位置為1表示相應(yīng)中斷源有請(qǐng)求,如果要清除某一位則向相應(yīng)位置寫(xiě)入1。

          rINTPND = 0x17; 也是清除ENIT0、1、2、4的中斷標(biāo)志位 INTPND同樣也是中斷源請(qǐng)求寄存器,如果有中斷發(fā)生,對(duì)應(yīng)位會(huì)自動(dòng)置1,如果要清除某一位也是向相應(yīng)位寫(xiě)入1。

          rEINTPEND=(1<<4); //清除ENIT4的中斷標(biāo)志位

          rINTMOD=0x0; //所有中斷為IRQ中斷 ,INITMOD為中斷模式寄存器,有FIQ快速中斷模式,當(dāng)INTMOD被置1時(shí)為FIQ模式,否則為IRQ模式,默認(rèn)為IRQ模式。

          rINTMSK &= ~0x17; //ENIT0、1、2、4中斷服務(wù)有效(這里就是使能外部中斷) INTMSK負(fù)責(zé)總的中斷向量屏蔽,當(dāng)被置1時(shí)則被屏蔽,否則沒(méi)有被屏蔽。

          rEINTMASK &= ~(1<<4);//EINT4中斷服務(wù)有效 EINTMASK負(fù)責(zé)具體某一中斷向量是否被屏蔽,當(dāng)被置1時(shí)則被屏蔽,否則沒(méi)有被屏蔽。

          pISR_EINT0 = (unsigned)IRQ_KEY4; //設(shè)置各中斷服務(wù)子程序地址

          我們?cè)?440addr.h頭文件里面找到 #define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))

          我們?cè)趏ption.inc匯編頭文件里面找到 _ISR_STARTADDRESS EQU 0x33ffff00 從上面二句我們知道,這是中斷服務(wù)的起始地址。

          pISR_EINT0是一個(gè)中斷入口地址變量,把該中斷處理函數(shù)的首地址傳遞給該變量,即中斷入口地址。

          一般來(lái)說(shuō),使用__irq這個(gè)關(guān)鍵詞來(lái)定義中斷處理函數(shù),這樣系統(tǒng)會(huì)為我們自動(dòng)保存一些必要的變量,并能夠在中斷處理函數(shù)執(zhí)行完后正確地返回。還需要注意的是,中斷處理函數(shù)不能有返回值,也不能傳遞任何參數(shù)。

          void __irq IRQ_KEY4(void)
          {
          rSRCPND |=1<<0; //清除中斷標(biāo)志位
          rINTPND |=1<<0;

          LED4_ON;
          Delay();
          LED4_OFF;
          }

          這是一個(gè)外部中斷0的處理函數(shù),

          rSRCPND |=1<<0;

          rINTPND |=1<<0;

          執(zhí)行完這二句后表示源掛起中斷標(biāo)志和具體某中斷掛起標(biāo)志都被清楚,其他外部中斷1、2、4處理函數(shù)亦是如此。

          ———————————————————————————————————

          到這里,這個(gè)main.c程序就講解完畢啦。你懂了嗎?



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉