一般的按鍵程式都是使用 Polling 方式,這種方式是比較簡單,只要在程式運作中,都會掃描每一個鍵有沒有按下去便可,但這種 Polling 方式在冗長的程式中,可能只是有一少段時間會掃描按鍵,如這次的掃描完成後,要反影按鍵的情況便要等到下一次了,所以 Polling 的方式在簡單程式中使用得較多,但在大程式便會使用得較少,通常大程式會使用中斷來處理。
在使用按鍵中斷程式會比較複習,相對地效率會高,因為當按鍵被按下,觸發中斷,便可以執行按鍵程式,不用等到掃描程式執行,執行完全後,便會返回主程式繼續執行,這樣中斷方法是需要處理器具備這功能才可以使用。這次使用了 18F4550 的 PORTB RB5 作為按鍵 I/O,因為 18F4550 的 PORTB <7:4> 是其中可用作中斷的接腳, PORTB<7:4> 在輸入狀態有改變,便會觸發中斷,執行程式。
▲ 單鍵中斷流程圖 |
PORTB 中斷特性當輸入狀態改變,從 0到1或 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.RBPU:1=Disable,0=Enable) 。設定 Falling/Tising Edge (INTCON2bits.INTEDG0:1=Rising,0=Falling) 觸發。Clear RBIF (INTCONbits.RBIE)旗號。Enable GIE。Enable 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%
天氣:多雲
沒有留言:
張貼留言