2013年11月9日土曜日

Raspberry PiでI2C LCD(その3)

ようやく、I2Cデバイス(LCD)にcでアクセスするプログラムを作成しました。
コンパイル後、実行するとI2C(LCD)デバイスであるMI2CLCD-01の液晶に「Hello I2C!」が
表示されるハズ。

<以下ソース>
#include
#include
#include

#define LCD_PORT (0x3e) // 液晶コントローラのI2Cアドレス
#define LCD_CMD (0x00) // 液晶コントローラのコマンドアドレス
#define LCD_DATA (0x40) // 液晶コントローラのデータアドレス
// グローバル変数
char currentMessage[17];        // 現在液晶に表示中のメッセージ
// 関数プロトタイプ宣言
int initMI2CLCD(void);  // MI2CLCD-01の初期化
int writeLCD(int fd, char *message);    // 液晶にメッセージを表示
int showMSG(int fd, char *temp);        // 文字列を表示
int main(void){
        int fdMI2CLCD;  // MI2CLCD用ファイルディスクリプタ
        char temp[17];  // 表示用文字列
        currentMessage[0] = 0x00;
        // MI2CLCD-01の初期化
        if ((fdMI2CLCD = initMI2CLCD()) == -1){
                printf("MI2CLCD-01の初期化に失敗");
                return 1;
        }
        while(1){
                strcpy(temp, "Hello I2C!");
                showMSG(fdMI2CLCD, temp);
                delay(1000);
        }
        return 0;
}
// MI2CLCD-01の初期化
// 引数:void
// 戻値:int    ファイルデスクリプタ(初期化失敗時は-1を返す)
int initMI2CLCD(void){
        int fd;         // コントローラのファイルデスクリプタ
        // 液晶コントローラを初期化し、コントローラにアクセスするための
        // ファイルディスクリプタを取得。
        // 初期化失敗時は-1を返して終了。
        if((fd = wiringPiI2CSetup(LCD_PORT)) == -1) return fd;
        // 初期化コマンドの送出。
        // アドレス0x00に書き込むと、コマンドとして扱われる(コマンドモード)
        // 0x00 は LCD_CMD として定義
        // Function Set (機能設定)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b00111000);  // 8ビットモード、2行表 示
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b00111001);  // 命令テーブルを選択
        // Internal OSC frequency (内部クロック周波数)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b00010100);  // 1/5バイアス,183Hz
        // Contrast Set (low byte) (コントラスト設定)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b01111000);  // 末尾4bitで指定
        // Power/ ICON control/ Contrast Set
        // パワー/アイコン制御/コントラスト設定
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b01011111);  // アイコンの表示 on
                                                                                                        // ブースター回路 on
                                                                // 内部フォロワ ・モードのコントラスト設定
        // Follower Control (フォロワ回路制御)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b01101010);  // フォロワ回路 on
        delay(250);                     // 電圧安定まで待つ
        // Display ON (表示ON/OFFコントロール)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b00001111);  // ディスプレイon
                                                                                                        // カーソル表示 on
                                                                                                        // ブリンク表示 on
        // Clear Display (表示をクリア)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b00000001);
        delay(2);
        // Entry Mode Set (エントリ・モード設定)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b00000110);  // カーソル右移動
        return fd;
}
// 液晶2行目にメッセージを表示。既存メッセージを上スクロール
// 引数:int    ファイルデスクリプタ
//   :char* 表示メッセージ(最大16文字)
// 戻値:int    現時点では常に0
int writeLCD(int fd, char* message){
        int i;
        char buf[17];
        // 2行目の表示内容を1行目にコピー
        // 液晶の現在の表示状態は読み込めないため、
        // グローバル変数 currentMessage を1行目に表示して代用
        strcpy(buf, currentMessage);
        // Set DDRAM Address (DDRAMアドレス設定)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b10000000);  // 1行目を指定
        for (i = 0; buf[i] != 0x00; i++){
        // アドレス0x40に書き込むと表示データとなる
        // 0x40 は LCD_DATA として定義
        wiringPiI2CWriteReg8(fd, LCD_DATA, buf[i]);
}
        // 2行目に新たなメッセージを表示させる
        strcpy(buf, message);
        // Set DDRAM Address (DDRAMアドレス設定)
        wiringPiI2CWriteReg8(fd, LCD_CMD, 0b11000000);  // 2行目を指定
        for (i = 0; buf[i] != 0x00; i++){
                wiringPiI2CWriteReg8(fd, LCD_DATA, buf[i]);
}
        // 新たなメッセージをグローバル変数に代入
        strcpy(currentMessage, message);
        return 0;
}
// 液晶に文字を表示
// 引数:int    ファイルデスクリプタ
//   :char[] 表示させる文字列
// 戻値:int    現時点では常に0
int showMSG(int fd, char *temp){
        char strMsg[17];        // 表示用文字列
        // 液晶表示用の文字列生成
        sprintf(strMsg, "%s\n", temp);  // 表示用文字列作成
        // 液晶に表示
        writeLCD(fd, strMsg);
        return 0;


0 件のコメント: