2011年11月25日 星期五

DIY - PIC: PIC18F4550 3x3 Keypad 鍵盤中斷程式 (一百二十二)

DIY - PIC PIC18F4550 3x3 Keypad 鍵盤中斷程式 (一百二十二)

因為 Microchip 18F4550 PORTB <7:4是其中可用作中斷的接腳,這次使用了 18F4550 PORTB RB5, RB6 RB7 作為按鍵中斷 I/O,當PORTB7:4 在輸入狀態有改變,便會觸發中斷,執行程式,而程式是利用 Polling 方式作掃描,只要按 9號鍵, Polling 便會完成,中斷也會結束,回到主程式。

3x3 鍵盤中斷流程圖
▼主程式
void main(void)
{

    // Set Up PortA
ADCON0 = 0x00;             // Disable the AD converter
ADCON1 = 0x0F;             // 0x0F = Set all port A,B to digital
TRISA  = 0b00000000;        // Setup PORTA as Output

    // Set up PortB as Keypad
    TRISB = 0b11100000;  
    // Set up PortB Interrupt
    INTCON2bits.RBPU = 0;     // Enable Pull up resistors at PORTB
    RCONbits.IPEN    = 1;          // Enable INT Priority
    INTCON2bits.RBIP = 1;       // Set PORTB INT as High Priority INT
INTCONbits.PEIE  = 1;       // Enable Peripheral INT
INTCONbits.RBIE  = 1;        // Enable PORTB INT
INTCONbits.GIEH  = 1;       // Enable All INT
    INTCONbits.RBIF  = 0;        // Clear PORTB INT Flag

    while(1)
    {
        LATAbits.LATA0 = 0;          // RA0=0 LED=OFF Scope=50ms
Delay10KTCYx(1);

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

▼中斷副程式
/******************************************************************************
 * 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
        {
        key_detect();
        }
}

/******************************************************************************
 * Subroutine: Scan Keypad
 * Scan the key press and return the position of key (Key=9 will exit)
 *****************************************************************************/
void key_detect() {
    char key1=0;
    char lastkey1=0;

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

if (high_int == 0){                             // 0=Normal High INT 99=First High INT
    LATB = 0b00000000;                   // Latch 1 to RB5
key1=kbd_getc();
    Delay10KTCYx(10);

do {
       key1 = kbd_getc();        // Read Ketboard Input
        if (key1 !=0 && lastkey1 != key1){
                lastkey1=key1;
            }
    Delay10KTCYx(100)   ;
} while(key1!=9);

   lastkey1 = 0;                          // Clear Key1
   key1 = 0;                               // Clear Key
   LATB = 0b11100000;          // Set PortB
}
else {
        key1 = kbd_getc();            // Scan to Clear PortB 5,6,7
        LATB = 0b11100000;      // Set PortB
        high_int = 0;}   // Clear High INT first time 

    INTCONbits.RBIE = 1;        // Enable PORTB INT
    INTCONbits.GIE  = 1;        // Enable All INT
  INTCONbits.RBIF=0;        // Clear PORTB INT Flag

}


3x3 鍵盤程式開始
▲讀取按鍵位置 1 資料
▲讀取按鍵位置 4 及位置 7資料
▲讀取按鍵位置 9資料
▲程式回到主程式及 LED 閃動

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

沒有留言:

張貼留言