2011年11月22日 星期二

DIY - PIC: PIC18F4550 單鍵中斷程式 (一百二十)

DIY - PIC PIC18F4550 單鍵中斷程式 (一百二十)

一般的按鍵程式都是使用 Polling 方式,這種方式是比較簡單,只要在程式運作中,都會掃描每一個鍵有沒有按下去便可,但這種 Polling 方式在冗長的程式中,可能只是有一少段時間會掃描按鍵,如這次的掃描完成後,要反影按鍵的情況便要等到下一次了,所以 Polling 的方式在簡單程式中使用得較多,但在大程式便會使用得較少,通常大程式會使用中斷來處理。

在使用按鍵中斷程式會比較複習,相對地效率會高,因為當按鍵被按下,觸發中斷,便可以執行按鍵程式,不用等到掃描程式執行,執行完全後,便會返回主程式繼續執行,這樣中斷方法是需要處理器具備這功能才可以使用。這次使用了 18F4550 PORTB RB5 作為按鍵 I/O,因為 18F4550 PORTB <7:4> 是其中可用作中斷的接腳, PORTB<7:4> 在輸入狀態有改變,便會觸發中斷,執行程式。

單鍵中斷流程圖
Microchip 18F4550 的蕊片是有中斷功能,首先要設定中斷,然後設定程式的入口及中斷服務副程式。

PORTB 中斷特性當輸入狀態改變,從 01 1 0,便會觸發中斷Power On/Reset RB<4:0> Analog Input 狀態。Power On/Reset RB<7:5> Digital Input 狀態。Power On/Reset PORTB Pull Up Resistor Disable

設定中斷設定 Port B I/O Digital Input設定 Pull Up Resistor (INTCON2bits.RBPU1=Disable0=Enable) 設定 Falling/Tising Edge (INTCON2bits.INTEDG01=Rising0=Falling) 觸發。Clear RBIF (INTCONbits.RBIE)旗號。Enable GIEEnable RBIE (INTCONbits.RBIE)
PORTB 中斷發生Read/Write Port B,可清除中斷。Clear RBIF 旗號。
▼中斷副程式
/******************************************************************************
 * Subroutine:  High Priority Interrupt Subroutine
 * When high interrupt occured GOTO here to check
 *****************************************************************************/
void high_isr()
{
    if(INTCONbits.RBIF ==1)        // if RB Port Change INT
        {
        INTCONbits.RBIE=0;        // Disable PORTB INT
        INTCONbits.RBIF=0;        // Clear PORTB INT Flag
        Key_detect();
        }
}

/******************************************************************************
 * Subroutine: Scan Keypad
 * Scan the key press and return the position of key (Key=9 will exit)
 *****************************************************************************/
void Key_detect(void)
{

INTCONbits.RBIF=0;        // Clear PORTB INT Flag

if (KeyMode==0){
    KeyMode=1;
    if (PORTBbits.RB5 == 0){
        putrsXLCD("0");
        }
        else {
        putrsXLCD("1");
        }
}
    if(PORTBbits.RB5 == 1) KeyMode = 0;

INTCONbits.RBIE = 1;    // Enable PORTB INT
INTCONbits.GIE=1;        // Enable All INT
}


▼主程式
void main(void)
{

    //Initialise PORTB
    TRISB = 0b00100000;                    // Set RB5 as Input

    OpenPORTB(PORTB_CHANGE_INT_ON &
              PORTB_PULLUPS_ON);

            RCONbits.IPEN   = 1;           // Enable INT Priority
            INTCON2bits.RBIP= 1;        // Set PORTB INT as high Priority INT
            INTCONbits.RBIE = 1;         // Enable PORTB INT
            INTCONbits.PEIE = 1;         // Enable Peripheral INT
            INTCONbits.GIE  = 1;          // Enable All INT
            INTCONbits.RBIF = 0;         // Clear PORTB INT Flag
   
while(1) {

        LATAbits.LATA0 = 0;           // RA0=0 LED=OFF Scope=50ms
        Delay10KTCYx(1);              // 10,000 x 1 x (4 x 0.05us) = 2ms
                           
        LATAbits.LATA0 = 1;           // RA0=1 LED=ON Scope=1
        Delay10KTCYx(1);               // 10,000 x 1 x (4 x 0.05us) = 2ms
                                                        // Scope = 2ms
}
   
} // Main End


PIC18F4550 單按鍵板接至主控板
PIC18F4550 單鍵程式開始
PIC18F4550 讀取按鍵 ON/OFF資料

2011   11 22 天氣報告
氣溫:21.1 @ 22:00 
相對濕度:百分之65% 
天氣:多雲

沒有留言:

張貼留言