※これは Hightec_Cのソースコードです。拡張子を〜.cに変えて下さい。 /***************************************************** * LCD(I2C)のテストプログラム for 12f683 * I2Cインターフェースで接続 * HI-TECH Cを使用 * * I2Cで送信するデータ(8bit)とLCD側端子の対応表 * LCD D7 D6 D5 D4 BL E RW RS * PCF8574T P7 P6 P5 P4 P3 P2 P1 P0 ******************************************************/ #include #define _XTAL_FREQ 4000000 // クロック周波数設定 // I2c スレーブ・アドレス 0x27 + "0" => 0x4E // 0x27を左に1ビットシフトし、右端にwrite=0 を付加 // (010 0111)+(出力"0"を右端に付ける)⇒0100 1110 #define ADDR 0x4E #define SDA GP5 #define SCL GP4 #define TRISSDA TRISIO5 /***** コンフィギュレーションの設定 ********/ __CONFIG(FOSC_INTOSCIO // INTOSCIO oscillator I/O function & WDTE_OFF // Watchdog Timer disabled & PWRTE_ON // Power-up Timer enabled & BOREN_ON // Brown Out enabled & MCLRE_ON // MCLR RA5はリセット & CP_OFF // Program memory code protection is disabled & IESO_OFF //Internal External Switchover mode is disabled & FCMEN_OFF);// Fail-Safe Clock Monitor is disabled void I2c_Start(void); void I2c_Stop(void); unsigned char I2c_Out(unsigned char data); void lcd_common(unsigned char data); void lcd_data(unsigned char data); void lcd_cmd(unsigned char data); void lcd_init(void); void lcd_str(char* ptr); void lcd_clear(void); void delay_10ms(unsigned int t1); void delay_10us(unsigned int t2); void Hyouji(); // CGRAM に格納する内容(下側の5ビット) const char custom[][8] = { // 0x1F→0b11111 { 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00 }, // char 1 { 0x18, 0x1C, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }, // char 2 { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x07, 0x03 }, // char 3 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F }, // char 4 { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1C, 0x18 }, // char 5 { 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F }, // char 6 { 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F }, // char 7 { 0x03, 0x07, 0x0F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F } // char 8 }; // CGRAM(0x00-07)を組み合わせて作る数字(0-9)とコロン // 0x20は空白、0xFFは塗りつぶし、0xA5は点 // 左3個が1行目、右3個が2行目 const char BigNum[11][6] = { { 0x07, 0x00, 0x01, 0x02, 0x03, 0x04 }, // 0 { 0x00, 0x01, 0x20, 0x03, 0xFF, 0x03 }, // 1 { 0x05, 0x05, 0x01, 0xFF, 0x06, 0x06 }, // 2 { 0x00, 0x05, 0x01, 0x03, 0x06, 0x04 }, // 3 { 0x02, 0x03, 0xFF, 0x20, 0x20, 0xFF }, // 4 { 0xFF, 0x05, 0x05, 0x06, 0x06, 0x04 }, // 5 { 0x07, 0x05, 0x05, 0x02, 0x06, 0x04 }, // 6 { 0x00, 0x00, 0x01, 0x20, 0x07, 0x20 }, // 7 { 0x07, 0x05, 0x01, 0x02, 0x06, 0x04 }, // 8 { 0x07, 0x05, 0x01, 0x06, 0x06, 0x04 }, // 9 { 0x20, 0xA5, 0x20, 0x20, 0xA5, 0x20 } // : }; // CGRAM用のデータ(custom)をメモリに格納する関数 void lcd_Def_Char(char adrs, char *pattern){ lcd_cmd(0x40 | (adrs << 3)); //CGRAMアドレス (adrs: 0-7) for(char i=0; i<8; i++){ lcd_data(pattern[i]); } } unsigned int Time; unsigned char s[4]; // s[0]分:s[2],s[3]秒 /******** メイン関数 ************/ void main(void){ OSCCON = 0x60; // Set to 4MHz GPIO = 0x30; // GP3,4,5 default High TRISIO = 0; // GP 全出力設定 ANSEL = 0x00; // デジタルに設定 CMCON0 = 0x07; // コンパレータオフ /* 液晶表示器の初期化 */ lcd_init(); // CGRAM0x00〜07へ配列customのフォントデータ書込み for(char j=0; j<8; j++){ lcd_Def_Char(j, &custom[j][0]); } // 初期値設定 Time = 0; GP2 = 0; // 動作確認用LED /**** メインループ *****/ while(1){ GP2 ^= 1; Hyouji(); if(Time++ > 599)Time = 0; delay_10ms(50); } } // 表示用関数 void Hyouji(){ // Time(秒数)を分(s[0])+コロン(s[1])+秒(s[2]s[3])に if(Time < 60){ s[0] = 'N'; // 'N'は記号 s[1] = 'N'; // コロン無し }else{ s[0] = (Time / 60); s[1] = 10; // コロン有り } if(Time < 10){ s[2] = 'N'; }else{ s[2] = (Time % 60) / 10; } s[3] = Time % 10; // 表示は左から unsigned char adr1 = 0x80; // 1行目左 unsigned char adr2 = 0xC0; // 2行目左 for(char k=0; k<4; k++){ // 4文字分 if(s[k] == 'N'){ // 値が無い時は adr1 += 4; // 4桁(文字3桁+空白1桁)右へ adr2 += 4; continue; } lcd_cmd(adr1); // 書き始め:左上へ unsigned char Ban; Ban = s[k]; for(char m=0; m<3; m++){ // 上3桁表示 lcd_data(BigNum[Ban][m]); } lcd_cmd(adr2); // 下3桁表示 for(char n=3; n<6; n++){ lcd_data(BigNum[Ban][n]); } adr1 += 4; // 4桁(文字3桁+空白1桁)右へ adr2 += 4; } } /** Start Condiotion **/ void I2c_Start(void){ // SCL,SDAは通常:High SDA = 0; // 先に SDA=Low TRISSDA = 0; // SDA出力 } /** Stop Condition **/ void I2c_Stop(void){ SCL = 0; // SCL Low SDA = 0; // SDA Low TRISSDA = 0; // 出力モードに戻す SCL = 1; // 先にSCLをHigh SDA = 1; // 後からSDAをHigh } /******************************* * I2c_で1バイト出力(1ビットずつ) ********************************/ unsigned char I2c_Out(unsigned char data){ int i; unsigned char BitPos, ACK; TRISSDA = 0; // SDA出力モード BitPos = 0x80; // ビット位置初期値(左端) for(i=0; i<8; i++) // 8ビット繰り返し { SCL = 0; // SCL Low if((data & BitPos) != 0) // ビット出力 SDA = 1; // SDA High else SDA = 0; // SDA Low BitPos = BitPos >> 1; // ビット位置移動 SCL = 1; // SCL Highに戻す } /* Ack チェック */ SCL = 0; // クロック1Low TRISSDA = 1; // 入力モードにしてACK入力 ACK = SDA; // ACKチェック for delay ACK = SDA; // ACKチェック SCL = 1; // クロックHighに戻す return(ACK); // ACKを戻り値とする } /********************************* * アダプターへデータ送信(基本) *********************************/ void lcd_common(unsigned char data){ I2c_Start(); // スタート I2c_Out(ADDR); // アドレス I2c_Out(data); // 表示データ出力 I2c_Stop(); // ストップ delay_10us(3); // 30μsec待ち } /********************************* * 液晶へ1文字表示データ出力 *********************************/ void lcd_data(unsigned char data) { unsigned char hydata; // 上位4ビット hydata = data & 0xf0 | 0x0D; // +Backlight,EN,RS lcd_common(hydata); delay_10us(1); lcd_common(hydata & ~0x04); // Enable_Pulse -> Low delay_10us(1); // 下位4ビット hydata = (data << 4) & 0xf0 | 0x0D; // +Backlight,EN,RS lcd_common(hydata); delay_10us(1); lcd_common(hydata & ~0x04); // Enable_Pulse -> Low delay_10us(5); } /******************************* * 液晶へ1コマンド出力 *******************************/ void lcd_cmd(unsigned char data) { unsigned char command; // 上位4ビット command = data & 0xf0 | 0x0C; // +Backlight,EN,(RS:0) lcd_common(command); delay_10us(1); lcd_common(command & ~0x04); // Enable_Pulse -> Low delay_10us(1); // 下位4ビット command = (data << 4) & 0xf0 | 0x0C;// +Backlight,EN lcd_common(command); delay_10us(1); lcd_common(command & ~0x04); // Enable_Pulse -> Low delay_10us(5); } /******************************* * 初期化関数 *******************************/ void lcd_init(void){ delay_10ms(10); // 4bit_mode & BackLight,EN lcd_common(0x2C); // '2'のデータと'1100' delay_10us(1); lcd_common(0x2C & ~0x04);// Enable を 0 に delay_10us(5); // ここから4ビット通常モード delay_10us(10); lcd_cmd(0x28); // 4ビット × 2, 2line delay_10us(10); lcd_cmd(0x08); // Display off,Cutsor off Blink off delay_10us(10); lcd_cmd(0x01); // Display clear delay_10ms(1); lcd_cmd(0x06); // Entry mode delay_10us(10); lcd_cmd(0x0c); // Display on,Cursor off delay_10us(10); } /****************************** * 全消去関数 ******************************/ void lcd_clear(void) { lcd_cmd(0x01); //初期化コマンド出力 } /***************************** * 文字列表示関数 *****************************/ void lcd_str(char *ptr) { while(*ptr != 0) //文字取り出し lcd_data(*ptr++); //文字表示 } /****************************** * 遅延関数 ******************************/ void delay_10ms(unsigned int t1){ while(t1--){ __delay_ms(10); } } void delay_10us(unsigned int t2){ while(t2--){ __delay_us(10); } }