// PIC16F874A Configuration Bit Settings // 'C' source line config statements // 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) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include #define _XTAL_FREQ 20000000 // 20MHz #define INT PORTAbits.RA0 #define CLK PORTAbits.RA1 #define DAT PORTBbits.RB0 #define WAIT 20 // g800エミュレータのCTRL+キーのコードは OADG USBコード + 0x80にした // SHIFTと2ndF(E1/E5)は例外 // 括弧()は独自コード 0x81 0x82 // OFF ◁ L I P const unsigned char keyMapCD[5] = { 0x29, 0x50, 0x0F, 0x0C, 0x13 }; // A Z BASIC nPr 2ndF const unsigned char keyMapDD[5] = { 0x04, 0x1D, 0x3A, 0x91, 0xE5 }; const unsigned char keyMapCB[5][7] = { {0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18}, // Q W E R T Y U {0x4F, 0x84, 0x27, 0x37, 0x08, 0x57, 0x28}, // ▷ ANS 0 . EXP + RET {0x33, 0x92, 0x1E, 0x1F, 0x20, 0x2D, 0xA8}, // ; CONST 1 2 3 - M+ {0x12, 0x49, 0x21, 0x22, 0x23, 0x55, 0xAE}, // O INS 4 5 6 * RCM {0x2A, 0x93, 0x24, 0x25, 0x26, 0x54, 0x82} // BS π 7 8 9 / ) }; const unsigned char keyMapDB[5][7] = { {0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E}, // S D F G H J K {0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36}, // X C V B N M , {0x3B, 0x39, 0xE2, 0x2B, 0x2C, 0x51, 0x52}, // TEXT CAPS カナ TAB SPC ↓ ↑ {0x87, 0x95, 0x94, 0xA3, 0x81, 0x8C, 0x90}, // →DEG √ x2 y2 ( 1/x MDF {0x96, 0x86, 0x8f, 0x8A, 0x97, 0x89, 0x4A} // sin cos ln log tan F⇔E CLS }; // SHIFT ON/BRK RESET const unsigned char keyMapEX[3] = { 0xE5, 0x48, 0x41 }; unsigned char outC[6] = {0b11110100, 0b01110101, 0b10110101, 0b11010101, 0b11100101, 0b11110101}; unsigned char outD[6] = {0b00111101, 0b01011101, 0b01101101, 0b01110101, 0b01111001, 0b01111101}; unsigned char keyStatCD[5], keyStatDD[5]; unsigned char keyStatCB[5][7], keyStatDB[5][7]; unsigned char keyStatEX[3]; unsigned char portIn, bitScan; void sendKeycode(unsigned char code) { INT = 0; __delay_us(WAIT); for(int i=0; i<8; i++) { DAT = (code >> i) & 1; CLK = 0; __delay_us(WAIT); CLK = 1; __delay_us(WAIT); } INT = 1; } void main(void) { ADCON0bits.ADON = 0; // ADコンバータ電力カット CVRCONbits.CVREN = 0; // コンパレータ電力カット CVRCONbits.CVROE = 0; // コンパレータ VrefをRA2から切り離し TRISEbits.PSPMODE = 0; // PORTDはデジタルI/Oにする(PSPオフ) SSPCONbits.SSPEN = 0; // SPI/I2C禁止 RC3/RC4はデジタルI/Oにする RCSTAbits.SPEN = 0; // シリアルポート禁止 RC6/RC7はデジタルI/Oにする ADCON1 = 0b00000110; // VREF使わない RA2/RA3はデジタルI/Oにする CMCON = 0b00000111; // コンパレータOFF OPTION_REGbits.nRBPU = 0; // PORTBを内部プルアップ // I/O設定 0..OUTPUT 1..INPUT TRISA = 0b00000000; TRISB = 0b11111110; // RB0 OUTPUT TRISC = 0b00001010; // RC1 RC3 外部10kΩプルアップ TRISD = 0b10000010; // RD1 RD7 外部10kΩプルアップ // 出力 LOW..0 HI..1 PORTA = 0b00000011; // RA0 RA1 HIGH PORTB = 0b00000000; PORTC = 0b11110101; PORTD = 0b01111101; //キー状態初期化 for(int i=0; i<5; i++) { keyStatCD[i] = 1; keyStatDD[i] = 1; for(int j=0; j<7; j++) { keyStatCB[i][j] = 1; keyStatDB[i][j] = 1; } } for(int i=0; i<3; i++) keyStatEX[i] = 1; while(1) { // PORTC(OUT)とRD7(IN)の通電を調べる for(int i=0; i< 5; i++) { PORTC = outC[i]; bitScan = PORTDbits.RD7; if(bitScan != keyStatCD[i]) { if(!bitScan) // キーが押された sendKeycode(keyMapCD[i]); keyStatCD[i] = bitScan; } } PORTC = outC[5]; // PORTD(OUT)とRD7(IN)の通電を調べる for(int i=0; i< 5; i++) { PORTD = outD[i]; bitScan = PORTDbits.RD7; if(bitScan != keyStatDD[i]) { if(!bitScan) // キーが押された sendKeycode(keyMapDD[i]); keyStatDD[i] = bitScan; } } PORTD = outD[5]; // PORTC(OUT)とPORTB(IN)の通電を調べる for(int i=0; i< 5; i++) { PORTC = outC[i]; portIn = PORTB; for(int j=0; j<7; j++) { bitScan = (portIn >> (j + 1)) & 1; if(bitScan != keyStatCB[i][j]) { if(!bitScan) // キーが押された sendKeycode(keyMapCB[i][j]); keyStatCB[i][j] = bitScan; } } } PORTC = outC[5]; // PORTD(OUT)とPORTB(IN)の通電を調べる for(int i=0; i< 5; i++) { PORTD = outD[i]; portIn = PORTB; for(int j=0; j<7; j++) { bitScan = (portIn >> (j + 1)) & 1; if(bitScan != keyStatDB[i][j]) { if(!bitScan) // キーが押された sendKeycode(keyMapDB[i][j]); keyStatDB[i][j] = bitScan; } } } PORTD = outD[5]; // SHIFT ON/BRK RESETの通電を調べる PORTDbits.RD4 = 0; bitScan = PORTCbits.RC1; if(bitScan != keyStatEX[0]) { if(!bitScan) // キーが押された sendKeycode(keyMapEX[0]); keyStatEX[0] = bitScan; } PORTDbits.RD4 = 1; PORTCbits.RC2 = 0; bitScan = PORTCbits.RC3; if(bitScan != keyStatEX[1]) { if(!bitScan) // キーが押された sendKeycode(keyMapEX[1]); keyStatEX[1] = bitScan; } PORTCbits.RC2 = 1; PORTDbits.RD0 = 0; bitScan = PORTDbits.RD1; if(bitScan != keyStatEX[2]) { if(!bitScan) // キーが押された sendKeycode(keyMapEX[2]); keyStatEX[2] = bitScan; } PORTDbits.RD0 = 1; } return; }