<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM裸機(jī)程序設(shè)計(jì)—按鍵中斷程序設(shè)計(jì)

          ARM裸機(jī)程序設(shè)計(jì)—按鍵中斷程序設(shè)計(jì)

          作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
          首先是按鍵中斷處理過(guò)程:

          1、中斷控制器匯集各類外設(shè)發(fā)出的中斷信號(hào),然后告訴CPU
          2、CPU保存當(dāng)前程序的運(yùn)行環(huán)境(各個(gè)寄存器等),調(diào)用中斷服務(wù)程序(ISR,Interrupt Service Routine)
          3、在ISR中通過(guò)讀中斷控制器、外設(shè)的相關(guān)寄存器來(lái)識(shí)別這是哪個(gè)中斷,并進(jìn)行相應(yīng)的處理
          4、清楚中斷:通過(guò)讀寫(xiě)中斷控制器和外設(shè)的相關(guān)寄存器來(lái)實(shí)現(xiàn)
          5、最好恢復(fù)中斷程序的運(yùn)行環(huán)境(即上面保存的各個(gè)寄存器等),繼續(xù)執(zhí)行

          本文引用地址:http://www.ex-cimer.com/article/201611/318240.htm

          按鍵中斷程序設(shè)計(jì)流程:
          1、按鍵以及按鍵中斷初始化
          1)對(duì)按鍵中斷端口初始化,設(shè)置為特殊功能模式(10)
          2)設(shè)置外部中斷觸發(fā)方式(EXTINTn低電平觸發(fā)000、高電平觸發(fā)001、上升沿觸發(fā)11x、下降沿觸發(fā)01x)
          3)清外部中斷掛起寄存器(EINTPEND)、源掛起寄存器(SRCPND)、中斷掛起寄存器(INTPND),對(duì)其寫(xiě)1清零,防止原有中斷產(chǎn)生的干擾
          4)中斷入口函數(shù),也就是把中斷服務(wù)子程序賦給對(duì)應(yīng)的中斷入口地址(pISR_EINT8_23)
          5)關(guān)閉外部中斷屏蔽寄存器(EINTMASK)和中斷屏蔽寄存器(INTMSK),也就是使能中斷,0使能,1屏蔽
          2、按鍵中斷服務(wù)子程序
          1)清源掛起寄存器(SRCPND)和中斷掛起寄存器(INTPND)
          2)通過(guò)判斷EINTPEND相應(yīng)的位來(lái)確定是那個(gè)按鍵產(chǎn)生了中斷,然后執(zhí)行相應(yīng)的程序,并且對(duì)EINTPEND寫(xiě)1清除相應(yīng)位,防止反復(fù)發(fā)生中斷

          源程序:

          //Main.c

          /*
          實(shí)驗(yàn)環(huán)境:mini2440開(kāi)發(fā)板
          完成日期:2011.4.13
          作者:阿龍
          實(shí)現(xiàn)功能:用中斷方式,當(dāng)按下K1時(shí)全亮,按下K2時(shí)計(jì)數(shù),按下K3時(shí)流水燈,按下K4時(shí)全滅

          遇到的問(wèn)題:就是我采用低電平觸發(fā)的時(shí)候,每次按鍵一次都會(huì)進(jìn)入兩次中斷,這個(gè)有點(diǎn)沒(méi)明白,也就是說(shuō)當(dāng)執(zhí)行流水燈的時(shí)候,會(huì)循環(huán)6次。但是當(dāng)執(zhí)行流水燈的時(shí)候我按下計(jì)數(shù)的按鍵之后,一切都正常,很怪異。

          我采用低電平觸發(fā)的時(shí)候,計(jì)數(shù)正常,流水燈有問(wèn)題。這個(gè)問(wèn)題等待以后解決。
          */
          #defineGLOBAL_CLK1
          #include
          #include
          #include "def.h"
          #include "option.h"
          #include "2440addr.h"
          #include "2440lib.h"
          #include "2440slib.h"
          #include "mmu.h"
          #include "profile.h"
          #include "memtest.h"

          /*
          函數(shù)聲明
          */
          void delay(int times);
          void LED_init(void);
          void KEY_init(void);
          //void LED_run(int num);
          void LED_ql(void);
          void LED_qm(void);
          void LED_lsd(void);
          void LED_js(void);
          void KEYint_init(void);
          static void __irq keyhandl(void);
          /*
          主函數(shù)
          */
          void Main(void)
          {
          MMU_Init();
          LED_init(); //LED燈初始化
          KEY_init(); //按鍵初始化
          KEYint_init(); //按鍵中斷初始化
          while(1);
          }
          /*
          按鍵中斷初始化
          */
          void KEYint_init(void)
          {
          //rEXTINT1 &=~((0xa<<0)|(0xa<12)|(0xa<<20)|(0xa<<24));//設(shè)置外部中斷觸發(fā)方式為下降沿觸發(fā)
          rEXTINT1 &=~((0xf<<0)|(0xf<<12)|(0xf<<20)|(0xf<<24));//設(shè)置外部中斷觸發(fā)方式為低電平有效
          rEINTPEND |=(1<<8)|(1<<11)|(1<<13)|(1<<14);//清外部中斷掛起寄存器
          ClearPending(BIT_EINT8_23);//清源中斷掛起寄存器和中斷掛起寄存器,防止干擾

          pISR_EINT8_23 =(U32)keyhandl;//中斷入口函數(shù)
          rEINTMASK &= ~((1<<8)|(1<<11)|(1<<13)|(1<<14));//關(guān)閉外部中斷屏蔽(也就是使能中斷)
          EnableIrq(BIT_EINT8_23);//中斷使能,其實(shí)就是關(guān)閉中斷屏蔽
          }
          /*
          按鍵中斷服務(wù)子程序
          */
          static void __irq keyhandl(void)
          {
          /*if(rINTPND == BIT_EINT8_23)
          {
          ClearPending(BIT_EINT8_23);
          switch(rEINTPEND &0x6900)
          {
          case (1<<8): rEINTPEND |= 1<<8;LED_run(4);LED_run(1);break;
          case (1<<11):rEINTPEND |= 1<<11;LED_run(4);LED_run(2);break;
          case (1<<13):rEINTPEND |= 1<<13;LED_run(4);LED_run(3);break;
          case (1<<14):rEINTPEND |= 1<<14;LED_run(4);break;
          }
          }*/
          //方式二
          if(rINTPND == BIT_EINT8_23)
          {
          ClearPending(BIT_EINT8_23);

          if(rEINTPEND &(1<<8))
          {
          rEINTPEND |= 1<<8;//清外部中斷掛起寄存器,防止反復(fù)發(fā)生中斷
          //LED_qm();
          LED_ql();
          }
          if(rEINTPEND &(1<<11))//當(dāng)我采用下降沿觸發(fā)的時(shí)候,這個(gè)程序執(zhí)行正常
          {
          rEINTPEND |= 1<<11;
          //LED_qm();
          LED_js();
          }
          if(rEINTPEND &(1<<13))//不管用什么觸發(fā),這個(gè)程序都要進(jìn)入兩次中斷,就算我采用下降沿,

                      //我一直按著按鍵,程序就會(huì)一直執(zhí)行,理論上應(yīng)該沒(méi)有下降沿就會(huì)執(zhí)行程序一次
          {
          rEINTPEND |= 1<<13;
          //LED_qm();
          LED_lsd();
          }
          if(rEINTPEND &(1<<14))
          {
          rEINTPEND |= 1<<14;
          LED_qm();
          }
          }
          }
          /*
          延時(shí)函數(shù)
          */
          void delay(int times)
          {
          int x,y;
          for(x=times;x>0;x--)
          for(y=500;y>0;y--);
          }
          /*
          LED初始化
          */
          void LED_init(void)
          {
          rGPBCON &=~((0x3<<10)|(0x3<<12)|(0x3<<14)|(0x3<<16));//GPB0設(shè)置為保留不用
          rGPBCON |= ((0x1<<10)|(0x1<<12)|(0x1<<14)|(0x1<<16));//設(shè)置GPB5,GPB6,GPB7,GPB8,為輸入模式(rGPBCON對(duì)應(yīng)位為01)
          rGPBUP =0xFFFFFFFF;
          }
          /*
          按鍵初始化
          */
          void KEY_init(void)
          {
          rGPGCON &=~((0x3<<0)|(0x3<<6)|(0x3<<10)|(0x3<<12)|(0x3<<14)|(0x3<<22));
          rGPGCON |= ((0x2<<0)|(0x2<<6)|(0x2<<10)|(0x2<<12)|(0x2<<14)|(0x2<<22));
          rGPGUP =0xFFFFFFFF;
          rGPBDAT |= (1<<5)|(1<<6)|(1<<7)|(1<<8);//全部讓他滅,防止干擾
          }
          /*
          LED燈的運(yùn)行效果選擇
          */
          /*void LED_run(int num)
          {
          switch(num)
          {
          case 1: LED_ql();break;
          case 2: LED_js();break;
          case 3: LED_lsd();break;
          case 4: LED_qm();break;
          }
          }*/
          /*
          LED燈全亮
          */
          void LED_ql(void)
          {
          rGPBDAT &= (0<<5)|(0<<6)|(0<<7)|(0<<8);
          }
          /*
          LED燈全滅
          */
          void LED_qm(void)
          {
          rGPBDAT |= (1<<5)|(1<<6)|(1<<7)|(1<<8);
          }
          /*
          流水燈
          */
          void LED_lsd(void)
          {
          int i;
          for(i=3;i>0;i--)//流水燈循環(huán)3次
          {
          rGPBDAT &= (0<<5)|(1<<6)|(1<<7)|(1<<8);
          delay(40000);
          rGPBDAT |= (1<<5)|(1<<6)|(1<<7)|(1<<8);


          rGPBDAT &= (1<<5)|(0<<6)|(1<<7)|(1<<8);
          delay(40000);
          rGPBDAT |= (1<<5)|(1<<6)|(1<<7)|(1<<8);

          rGPBDAT &= (1<<5)|(1<<6)|(0<<7)|(1<<8);
          delay(40000);
          rGPBDAT |= (1<<5)|(1<<6)|(1<<7)|(1<<8);

          rGPBDAT &= (1<<5)|(1<<6)|(1<<7)|(0<<8);
          delay(40000);
          rGPBDAT |= (1<<5)|(1<<6)|(1<<7)|(1<<8);
          }
          }
          /*
          LED以二進(jìn)制方式計(jì)數(shù)(0-15)
          */
          void LED_js(void)
          {
          int i;
          rGPBDAT=~0x02f;//最后四位設(shè)為1的目的主要是把蜂鳴器屏蔽掉,前面設(shè)為保留也不管用,只能這里設(shè)置
          for(i=0;i<15;i++)
          {
          delay(60000);
          //rGPBDAT=~rGPBDAT; //如果采用這個(gè)去取反,當(dāng)我單步調(diào)試的時(shí)候,蜂鳴器會(huì)發(fā)出響聲,所以我直接在下面語(yǔ)句中直接取反
          rGPBDAT=~(~rGPBDAT+0x020);//沒(méi)運(yùn)行一次,第5位加1進(jìn)位
          }
          }



          評(píng)論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();