<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > PIC單片機引腳中斷程序的設計技巧

PIC單片機引腳中斷程序的設計技巧

——
作者:山東省寧陽(yáng)一中 殷建彬 時(shí)間:2007-11-20 來(lái)源:?jiǎn)纹瑱C及嵌入式系統應用 收藏

1 簡(jiǎn) 述

    所有的中檔系列,PORTB端口最高的4個(gè)引腳(RB7~RB4)在設為輸入模式時(shí),當輸入電平由高到低或由低到高發(fā)生變化時(shí),可以讓單片機產(chǎn)生中斷。這就是通常所說(shuō)的引腳狀態(tài)變化中斷。

    在設計引腳中斷程序時(shí),有三個(gè)需要特別注意的地方。一是,在清除P0RTB中斷標志位RBIF之前,必須安排一條必不可少的,以PORTB端口數據寄存器PORTB為源寄存器的讀操作指令。放置這一指令的目的有時(shí)并不只是為了讀取有用的數據,而是為了取消狀態(tài)變化的硬件信號,以便順利清除RBIF標志位,為下一次中斷做好準備。二是,由于端口PORTB是引腳電子變化中斷,即無(wú)論引腳出現上升沿還是下降沿都會(huì )產(chǎn)生中斷請求,所以必須處理好不需要的虛假中斷。三是,一般都利用的引腳功能來(lái)檢測按鍵,所以必須處理好按鍵消抖的問(wèn)題。

2 引腳中斷程序設計

    在主程序里先設置有關(guān)的寄存器。

    ◇設置TRISB寄存器,使RB7~RB4相關(guān)的引腳處于輸入狀態(tài);
    ◇如果需要弱上拉,通過(guò)OPTION_REG的第7位設置;
    ◇RBIF=O;
    ◇RBIE=1;
    ◇GIF=1。

    響應狀態(tài)變化后的中斷服務(wù)程序。
    ◇檢查RBIF是否為l,為l則是引腳變化引起的中斷;
    ◇調用延時(shí)程序,延時(shí)20~30 ms,目的是為了按鍵去抖;
    ◇判斷是引腳出現上升沿還是下降沿引起的中斷;
    ◇調用按鍵處理程序;
    ◇讀PORTB口的值,取消狀態(tài)變化的硬件信號;
    ◇清除RBIF標志。

    筆者認為上面程序設計最大的問(wèn)題是在中斷程序里調用延時(shí)程序。大家知道,中檔只有8層深度的硬件堆棧,在中斷里調用于程序出現極易堆棧溢出的情況。另外,PIC單片機中斷程序人口只有一個(gè),在響應中斷的請求時(shí),PIC單片機就會(huì )自動(dòng)把全局中斷的使能位(INTCON的第7位GIF)清除,這樣其他中斷就暫時(shí)不能被響應(此時(shí),如果別的中斷發(fā)出的中斷請求,標志位將一直保留著(zhù)),直到這個(gè)中斷程序退出后才會(huì )得到響應。這就要求我們設計中斷程序的時(shí)候必須盡量短,避免調用子程序,更不要在中斷里進(jìn)行復雜的運算。

    下面給出筆者設計程序時(shí)的思路。

    當引腳狀態(tài)變化引起中斷時(shí),在中斷子程序里首先判斷引起中斷的原因是不是我們需要的變化引起的中斷。如果是,不要在這里延時(shí),而是設置一個(gè)標志位,接著(zhù)清除中斷標志,退出中斷。中斷程序如下:
else if((RBIE&RBlF)==1){ //如果引腳變化引起中斷
    if(RB4==0){ //RB4上的按鈕接地
    key=1; //按鍵標志位置位
    }
    RBIF=0; //清除引腳中斷標志位
    }

    其中,if(RB4==0)語(yǔ)句相當于讀取了PORTB端口數據寄存器,取消了狀態(tài)變化的硬件信號。

    下面詳細介紹怎么樣進(jìn)行按鍵去抖。

    首先,在定時(shí)器中斷里設置一個(gè)lms的時(shí)間基準標志位“SYSlms”,每到lms,“SYSlms”便置位。程序如下:
    unsigned char count;
    if((ToIE&TOIF)==1){ //定時(shí)器中斷
    TMRO+=0x09; //每250μs中斷一次
    if(count==4){
    count=0;
    SYSlms=l; //系統時(shí)間標志
    couot++;
    }   

    T0IF=0; //清除時(shí)鐘中斷標志位
    }

    有了這個(gè)時(shí)間基準,便可以在主程序里進(jìn)行按鍵去抖處理了。為了更好地利用這個(gè)時(shí)間基準,定義一個(gè)消息標志SYSTime,筆者把它稱(chēng)作時(shí)間消息。為了讓這個(gè)消息有自我發(fā)布和自我消失的功能.定義了如下一個(gè)宏:
    bit SYSTime;
    #defincTimeEnahle()SYSTime=0,if(SYSlms){SYSTime=l;SYSlms=0;)

    可以把TimeEnable()放到主程序死循環(huán)的任何地方,每當程序執行這個(gè)宏,SYSTime就會(huì )清零,這就是標志位的自我消失.如果在定時(shí)器時(shí)間基準標志位SYSlms已經(jīng)置位的話(huà),SYSTime就會(huì )置1,這樣別的程序就可以利用這個(gè)時(shí)間消息了,這就是消息的自我發(fā)布。下面就是利用這個(gè)時(shí)間消息來(lái)進(jìn)行按鍵延時(shí)去抖的,首先看一下按鍵掃描子程序;
    void seaakey(){
    unsigned char KeyTime,KeyTask;//定義任務(wù)時(shí)間參數、
    //任務(wù)參數
    switch(KeyTask){
    case0:if(key){
    KeyTime=30; //準備延時(shí)30 ms
    KeyTask++; //準備好下一個(gè)任務(wù)
    kcy=0;
    }
    break;
    case I:KeyTime--; //延時(shí)30 ms
    if(KeyTime==0)Key+ask++;
    break;
    case2;if(RB4==o){
    //調按鍵處理程序
    KeyTask=0;
    }
    else KeyTask=0;//退出任務(wù)
    break;
    }
}

    在主程序的死循環(huán)中這樣用:
    while(1){
    TimeEnable();
    If(SYSTime==1){scankey();)
    //在此可以添加其他程序

    只有有時(shí)問(wèn)消息的時(shí)候才執行按鍵掃描程序??梢钥吹?,進(jìn)入掃描程序執行第一次的時(shí)候,程序首先判斷按鍵標志位有沒(méi)有置位,置位的話(huà)(也就是有按鍵按下的話(huà)),任務(wù)時(shí)間參數(KeyTime)賦值為30,這是延時(shí)30ms,去抖,當然你也可以設置為其他的時(shí)間值;同時(shí)任務(wù)參數 (KeyTask)加1。1ms后,再進(jìn)入掃描程序,這個(gè)時(shí)候掃描程序執行casel的語(yǔ)句,這樣30次后(延時(shí)了30ms),任務(wù)參數(KeyTask)加1,值為2。lms后,再進(jìn)入掃描程序,將執行case 2的語(yǔ)句,首先在這里再次判斷是不是按鍵還在按下,如果是就調按鍵的處理程序,如果不是。就退出按鍵掃描程序。在這里,還可以加入按鍵是否抬起的判斷程序。

    這樣設計的引腳變化程序,CPU開(kāi)銷(xiāo)小,效率高,不會(huì )出現堆淺溢出的問(wèn)題,提高了系統的實(shí)時(shí)性。

 



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>