※これは Hightec_Cのソースコードです。 /***************************************************** * LCD(I2C)のテストプログラム for 12f683 * I2Cインターフェースで接続 * HI-TECH Cを使用 MPLAB IDE v8.84 * * 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 // クロック周波数設定 /***** コンフィギュレーションの設定 ********/ __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & BOREN_ON & MCLRE_ON & CP_OFF & IESO_OFF & FCMEN_OFF); /* I2c スレーブ・アドレス 0x27 + '0' => 0x4E */ #define ADDR 0x4E #define SDA GP5 #define SCL GP4 #define TRISSDA TRISIO5 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 i_to_str(char digit, unsigned int data, char *buffer); unsigned char Msg[10] = "Cnt = xxxx"; /******** メイン関数 ************/ void main(void){ unsigned int Count; OSCCON = 0x60; // クロック周波数 4MHz GPIO = 0x30; // GP4,GP5 default High TRISIO = 0; // GP 全出力設定 ANSEL = 0x00; // デジタルに設定 CMCON0 = 0x07; // コンパレータオフ /* 液晶表示器の初期化 */ lcd_init(); Count = 0; GP2 = 0; // 動作確認用LED /**** メインループ *****/ while(1){ GP2 ^= 1; // LED点滅 lcd_cmd(0x80); // カーソル移動 上左 lcd_str("LCD Test"); i_to_str(4, Count++, Msg+6); lcd_cmd(0xC0); // カーソル移動 下左 lcd_str(Msg); delay_10ms(50); } } /*************************************** * int整数からASCII文字に変換 ****************************************/ void i_to_str(char digit, unsigned int data, char *buffer){ char i; buffer += digit; // 最後の数字位置 for(i=digit; i>0; i--) { // 変換は下位から上位へ buffer--; // ポインター1 *buffer = (data % 10) + '0'; // ASCIIへ data = data / 10; // 次の桁へ } } /***************************** * 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_Pulse -> Low 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); } }