利用Time 1中斷,每0.1秒去掃描看沒有按鍵被按。
Time中斷可參考http://tomyam-yang.blogspot.com/2017/06/arduino-timer-as-counter.html
提升電阻參考https://www.arduino.cc/en/Tutorial/DigitalPins
volatile char key_pad;因為key_pad變數使用在中斷內如果不使用volatile去定義,有可能這一次編譯可以正常執行,下一次編譯卻有問題,詳細說明可參考http://newscienceview.blogspot.com/2013/09/c-volatile.html
將多維陣列keymap[][]傳入副函式scan_key的方法如下:
key_pad=scan_key(KEY_COLS,KEY_ROWS,(char *)keymap,colPins,rowPins);
key_pad=scan_key(KEY_COLS,KEY_ROWS,*keymap,colPins,rowPins);
key_pad=scan_key(KEY_COLS,KEY_ROWS,keymap[0],colPins,rowPins);
key_pad=scan_key(KEY_COLS,KEY_ROWS,&keymap[0][0],colPins,rowPins);
陣列的參數傳遞可以參考C陣列、[C++]如何將多維陣列傳入副函式、二維陣列與雙重指標之間的關係
char scan_key(byte,byte,char *,byte *,byte *); #define KEY_ROWS 4 // 按鍵模組的列數 #define KEY_COLS 4 // 按鍵模組的行數 const byte colPins[KEY_COLS] = {9, 8, 7, 6}; // 設定「行」腳位 const byte rowPins[KEY_ROWS] = {13, 12, 11, 10}; // 設定「列」腳位 const char keymap[KEY_ROWS][KEY_COLS] = { {'A', '7', '8', '9'}, {'B', '4', '5', '6'}, {'C', '1', '2', '3'}, {'D', 'E', 'F', '0'} }; volatile char key_pad; void setup() { byte i; //設定中斷1參數: TCCR1A=0x00; TCCR1B=0b00000101;//設定除頻1024 15625HZ TCNT1=-1562; //約0.1秒掃描一次 TIMSK1 |=0x01; //啟動Timer中斷 key_pad=0; for ( i = 0; i <= 3; i++) { pinMode(rowPins[i], INPUT); pinMode(colPins[i], OUTPUT); digitalWrite(colPins[i], HIGH); digitalWrite(rowPins[i], HIGH);//啟動上拉電阻 } Serial.begin(9600); } void loop() { while(key_pad) { Serial.println(key_pad); key_pad=0; } } ISR(TIMER1_OVF_vect) { TIMSK1 &=0xfe; key_pad=scan_key(KEY_COLS,KEY_ROWS,(char *)keymap,colPins,rowPins); TCNT1=-1562; TIMSK1 |=0x01; } char scan_key(byte col,byte row,char *key_map,byte *col_pin,byte *row_pin) { unsigned long time_; byte i,j; byte scanVal; // 暫存掃描到的按鍵值low or high time_=millis(); for (i = 0; i < row; i++) { //按著不放的情況下不用理它 scanVal=digitalRead(*(row_pin+i)); if (scanVal == LOW) { return 0; } } for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { digitalWrite(*(col_pin+j),LOW); scanVal=digitalRead(*(row_pin+i)); if (scanVal == LOW) { // 如果輸入值是「低電位」… for(;;) { if((millis()-time_)>1000) { return 0; } delay(100); scanVal=digitalRead(*(row_pin+i)); if (scanVal == LOW) { return *(key_map+i*row+j); } } } digitalWrite(*(col_pin+j),HIGH); } } return 0; }
沒有留言:
張貼留言