// CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #include #define _XTAL_FREQ 20000000 // 20MHz #define CLK PORTAbits.RA0 #define DAT PORTAbits.RA1 #define WAIT 20 #define BUFFER_SIZE 32 #define BREAK 0xF0 // Breakコード #define ONC 16 // ON/Cキーコード #define WAIT_HIGH while(CLK == 0); #define WAIT_LOW while(CLK == 1); void putKeycode(unsigned char); unsigned char getKeycode(void); void sendKeycode(void); unsigned char OP[5] = {0b11110100, 0b11101100, 0b11011100, 0b10111100, 0b01111100}; unsigned char buffer[BUFFER_SIZE]; unsigned char head, tail; int dataFlag; const unsigned char keyMap[5][5] = { { 1, 18, 2, 3, 0}, { 4, 14, 5, 6, 21}, {23, 20, 10, 11, 15}, {22, 99, 17, 13, 19}, { 8, 99, 9, 12, 7} }; unsigned char keyStat[5][5]; unsigned char keyStatExt; // "ON/C" unsigned char keyin; static int count = 0; void main(void) { ADCON0 = 0b00000000; // ADコンバータOFF ADCON1 = 0b00000110; // 全てデジタル RA2 RA3 Vref使わない CMCON = 0b00000111; // コンパレータOFF CCP1CON = 0b00000000; // CCP1オフ 設定しなくても問題ないかも CCP2CON = 0b00000000; // CCP2オフ 動作に関係ないけど念の為 TRISA = 0b00000001; TRISB = 0b00011111; TRISC = 0b11111100; PORTA = 0b00000000; PORTB = 0b00011111; PORTC = 0b00000000; OPTION_REGbits.nRBPU = 0; // PORTBを内部プルアップ //キー状態初期化 for(int i=0; i<5; i++) for(int j=0; j<5; j++) keyStat[i][j] = 1; keyStatExt = 1; head = 0; tail = 0; dataFlag = 0; __delay_ms(300); while(1) { if(CLK) sendKeycode(); for(int i=0; i<5; i++) { TRISC = OP[i]; __delay_ms(1); // 回路の安定を待つ for(int j=0; j<5; j++) { keyin = PORTB; keyin = (keyin >> j) & 1; if(keyin != keyStat[i][j]) { if(keyin) { putKeycode(BREAK); putKeycode(keyMap[i][j]); } else putKeycode(keyMap[i][j]); keyStat[i][j] = keyin; } } } TRISC = 0b11111000; __delay_ms(1); // 回路の安定を待つ keyin = PORTB; keyin = (keyin >> 3) & 1; if(keyin != keyStatExt) { if(keyin) { putKeycode(BREAK); putKeycode(ONC); } else putKeycode(ONC); keyStatExt = keyin; } } } // バッファにキーコードを入れる void putKeycode(unsigned char code) { unsigned char p; p = tail; buffer[p++] = code; if(p == BUFFER_SIZE) p = 0; if(p != head) tail = p; dataFlag = 1; } // バッファからキーコードを取り出す unsigned char getKeycode() { unsigned char val; val = buffer[head++]; if(head == BUFFER_SIZE) head = 0; if(head == tail) dataFlag = 0; return val; } void sendKeycode() { unsigned char code; if(dataFlag) code = getKeycode(); else code = 0xFF; WAIT_LOW for(int i= 0; i<8; i++) { WAIT_HIGH DAT = (code >> i) & 1; WAIT_LOW } }