//========================================================= // VividHobbyブログ連載 i2Cプログラム (1) // 目標 * LCD表示器に文字を表示する //========================================================= //------------------------ // 初期設定 //------------------------ #include #include #include #pragma config FOSC = HS //高速オシレーター(4MHz以上)使用 #pragma config WDTE = OFF //ウォッチドッグタイマーOFF #pragma config CP = OFF //コードプロテクションOFF #pragma config PWRTE = ON //パワーアップタイマーON #pragma config LVP = OFF// //PICのクロック設定 #define _XTAL_FREQ 12800000 //PICのクロックをHzで設定(12.8MHz) //モニター確認用LED #define RED_led RA0 //Red LED #define Yellow_led RA1 //Yellow LED //-------------------------------------------------------- // 関数定義エリア // i2c 基本入出力関数 //-------------------------------------------------------- void i2c_CONF(void); //i2c初期設定 void i2c_START(void); //スタートコンディション発行 void i2c_ReSTART(void); //再スタートコンディション発行 void i2c_STOP(void); //ストップコンディション発行 void i2c_WRITE(unsigned char); //1バイト書き込み unsigned char i2c_READ(void); //1バイト読み込み unsigned char i2c_READC(void); //1バイト連続読み込み //--------------------------------------------------------- // LCS表示制御コマンド //--------------------------------------------------------- void LCD_init(void); //LCDの初期設定 void LCD_Clear(int); //LCDクリア(0=全面、1=1行目、2=2行目) void LCD_puts(const char *p); //LCDへ連続文字表示 void LCD_Locate(unsigned char, unsigned char); //文字表示位置の設定 void LCD_CW(unsigned char); //LCDコマンド1バイト書き込み void LCD_DW(unsigned char); //LCDデータ1バイト書き込み //------------------------------ // その他関数 //------------------------------ void PIC_init(void); //PIC初期化 void Debug_RED(void); //デバッグ用赤色LED点滅 //--------------------------------------------------------- // 変数定義 //--------------------------------------------------------- int i, j; //ループカウンター int disp; //文字変換する数値を代入 unsigned char S_ADRS1 = 0xA0; // LCD Slave Address1(S_Adrs << 1) unsigned char RDDAT; //i2c受信関数データの一時保管 char str[10]; //文字変換結果代入 //------------------------------------------------------- // メインプログラム //------------------------------------------------------- main() { PIC_init(); // PICの入出力ポート、割り込み、AD変換など初期設定 i2c_CONF(); // PIC設定i2c用 //----------------------------- // PIC 起動確認用LED点滅 //----------------------------- RED_led = 0; // RED LED on __delay_ms(500); RED_led = 1; // RED LED off __delay_ms(500); RED_led = 0; // RED LED on __delay_ms(500); RED_led = 1; // RED LED off __delay_ms(2000); while (1) { LCD_init(); // LCD初期化、クリアディスプレイ //-------------------------- // LCD 初期メッセージ表示例 //-------------------------- LCD_CW(0x80); //LCDのデータ格納RAMのアドレスを先頭位置にセット LCD_DW('V'); //表示するデータとして、Vを送信 LCD_DW('i'); //同上 i を送信 LCD_DW('v'); LCD_DW('i'); LCD_DW('d'); LCD_DW(' '); __delay_ms(3000); //3秒待ち disp = 12345; itoa(str, disp, 10); //数字の123435を文字に10進数変換して表示 LCD_puts(str); __delay_ms(3000); //3秒待ち } } //-------------------- End of Main program -------------------------------- //======================================== //関数定義エリア //======================================== //---------------------------------- // PIC 初期設定 //---------------------------------- void PIC_init(void) { //PICのポート設定 ADCON0 = 0b10000000; //アナログ使用しない ADCON1 = 0b00000110; //For degital I/O TRISA = 0b00000000; TRISB = 0b00000000; TRISC = 0b10011000; // i2cポートは「入力モード」に設定する //ポート初期化 PORTA = 0b11111111; PORTB = 0b11111111; PORTC = 0b11111111; //割り込み不使用 INTCON = 0b00000000; //TMR0関係は使用しない設定に。 //TMRはフリーラン OPTION_REG = 0b11000000; TMR0 = 0; //周辺機器割り込み不使用 PIE1 = 0; //周辺機器割り込みフラグクリア PIR1 = 0; } //------------------------------------ // i2C READ one : 受信 = RDDAT //------------------------------------ unsigned char i2c_READ(void) { ACKDT = 1; RCEN = 1; while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す RDDAT = SSPBUF; SSPIF = 0; ACKEN = 1; while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す SSPIF = 0; return RDDAT; } //------------------------------------ // i2C READ Continue : 受信 = read_data //------------------------------------ unsigned char i2c_READC(void) { ACKDT = 0; RCEN = 1; while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す RDDAT = SSPBUF; SSPIF = 0; ACKEN = 1; while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す SSPIF = 0; return RDDAT; } //------------------------------------- // i2C WRITE (write_data) //------------------------------------- void i2c_WRITE(unsigned char w_data) { while (BF == 1); //BFが0になるまで待つ。1の間繰り返す。 SSPBUF = w_data; SSPIF = 0; while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す SSPIF = 0; } //----------------------------------- // i2C STOP Condition //----------------------------------- void i2c_STOP(void) { PEN = 1; while (SSPIF == 0); SSPIF = 0; } //---------------------------------- // i2C START Condition //---------------------------------- void i2c_START(void) { SEN = 1; while (SSPIF == 0); //SSPIFが1になるまで待つ。0の間繰り返す SSPIF = 0; } //---------------------------------- // i2C 設定初期化 //---------------------------------- void i2c_CONF(void) { SSPM3 = 1; SSPM2 = 0; SSPM1 = 0; SSPM0 = 0; SMP = 1; CKE = 0; SSPADD = 0x3F; SSPEN = 1; WCOL = 0; SSPOV = 0; } //----------------------------------------------------------- // Debug Red LED (OK) // 赤色LEDを点滅させてプログラム停止 (PORT RB7接続のLED) //------------------------------------------------------------ void Debug_RED() { while (1) { RED_led ^= 1; __delay_ms(50); } } //---------------------------------------------- // LCD Initialization // 画面クリア後カーソルはホームへセット // RAMメモリーポインター先頭 //----------------------------------------------- void LCD_init() { LCD_CW(0x01); // クリアディスプレイ LCD_CW(0x38); LCD_CW(0x0F); LCD_CW(0x06); LCD_CW(0x80); // 表示RAM領域アドレスポインターを先頭に } //----------------------------------------------- // LCD文字表示(連続) // 現在のカーソル位置から連続して文字を書き込む // 1行目、2行目の終端を越えた文字は無視される //------------------------------------------------ void LCD_puts(const char *p) { while (*p != '\0') { LCD_DW(*p); p++; } } //----------------------------------------- // LCD Cursor Control (x, y)) //----------------------------------------- void LCD_Locate(unsigned char x, unsigned char y) { unsigned char pos; pos = 0x40 * y + x; pos = pos + 0x80; LCD_CW(pos); } //--------------------------------------------- // LCD コマンド1バイト書き込み //--------------------------------------------- void LCD_CW(unsigned char lcd_cmd) { i2c_START(); i2c_WRITE(S_ADRS1); i2c_WRITE(0x00); i2c_WRITE(lcd_cmd); i2c_STOP(); __delay_ms(5); } //--------------------------------------------- // LCD データ1バイト書き込み //--------------------------------------------- void LCD_DW(unsigned char lcd_dat) { i2c_START(); i2c_WRITE(S_ADRS1); i2c_WRITE(0x80); i2c_WRITE(lcd_dat); i2c_STOP(); __delay_ms(5); } //////////////////// End Of Program ///////////////////////////