マトリクスキーパッド4×4 / Cで記述する

pp.419-420
同じことを今度はCで記述する。
f:id:ti-nspire:20200622160600p:plain:h315

  • サンプルファイル:
/*
下のように接続する。
ROW0 → PD7
ROW1 → PD6
ROW2 → PD5
ROW3 → PD4

COL3 → PD3
COL2 → PD2
COL1 → PD1
COL0 → PD0
*/

#define F_CPU 8000000UL

#include <avr/io.h>
#include "MatKeyClass.h"

const uint8_t KEYS[4][4] = {{ 0, 1, 2, 3},
                            { 4, 5, 6, 7},
                            { 8, 9,10,11},
                            {12,13,14,15}};

int main(){
    DDRB = 0xFF;

    MatKeyClass keypad;
    keypad.init();
    while(1){
        keypad.detectKey();
        PORTB = KEYS[keypad.getRow()][keypad.getCol()];
    }
    
    return 0;
}
  • ライブラリーのヘッダーファイル:
/*
下のように接続する。
ROW0 → PD7
ROW1 → PD6
ROW2 → PD5
ROW3 → PD4

COL3 → PD3
COL2 → PD2
COL1 → PD1
COL0 → PD0
*/

#ifndef MATKEYCLASS_H_
#define MATKEYCLASS_H_

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>

class MatKeyClass{
    private:
    uint8_t row, col;
    
    void waitForRelease();
    void waitForPress();
    void searchRow();
    
    public:
    void init();
    void detectKey();
    uint8_t getRow();
    uint8_t getCol();
    

    MatKeyClass();
};

#endif
  • ライブラリーの実装:
#include "MatKeyClass.h"

void MatKeyClass::init(){
    DDRD = 0xF0; // ポートDの上位ニブルを行(OUT)に、下位ニブルを列(IN)に接続する。
}
void MatKeyClass::waitForRelease(){
    PORTD = 0x0F;                 // すべての行をLにして、
    asm("NOP");
    while((PIND & 0x0F) != 0x0F); // すべてのキーから指が離れるまで(すべての列がHになるまで)とどまる。
}
void MatKeyClass::waitForPress(){
    while((PIND & 0x0F) == 0x0F);              // どれかキーが押されるまで(どれか列がLになるまで)とどまって、
    _delay_ms(20);                             // どれかキーが押されたらバウンスの収まるのを待って、
    for(uint8_t i=0; i<4; i++){
        if((~(PIND & 0x0F) & 0x0F) == 1 << i){ // やはり押されていたら、
            col = i;                           // 列番号を取得して、
            break;                             // 抜ける。
        }
    }
}
void MatKeyClass::searchRow(){
    for(uint8_t i=0; i<4; i++){
        PORTD = ~(1 << (7 - i));   // 0行目から1行ずつ順番にLにして、
        asm("NOP");
        if((PIND & 0x0F) != 0x0F){ // どれかキーの押下が見つかったら、
            row = i;               // 行番号を取得して、
            break;                 // 抜ける。
        }
    }
}
void MatKeyClass::detectKey(){
    waitForRelease();
    waitForPress();
    searchRow();
}
uint8_t MatKeyClass::getRow(){
    return row;
}
uint8_t MatKeyClass::getCol(){
    return col;
}


MatKeyClass::MatKeyClass(){}