C言語

I2Cを使ってLCDに文字を表示させる!①(C言語)

I2Cを使ってLCDに文字を表示させる!①(C言語)

スポンサーリンク

こんにちは。駆け出しエンジニアのまっきーです。

今回は、I2Cを使ってLCDに文字表示をさせたいと思います。

準備、用語解説

使用したもの

  • RaspberryPi3B+
  • I2C LCD Display(16*2)
  • 1602 I2Cキャラクタ表示液晶
  • 8ピンジャンパワイヤ(メス・メス)

↑8ピンでなくてもよい

上記のもの(RaspberryPiを除く)は全て下記のセットに同梱されています。

https://amzn.to/2QKiZzf

それではまずI2Cとは何かから説明していきます。

I2Cとは

 

I2Cとは、クロックに同期させて通信を行う同期式シリアル通信です。

この通信では2本の信号線を用います。

  • SDA(Serial DAta line) データ信号
  • SCL(Serial Clock Line) クロック信号

SCLで同期をとり、SDAでデータを送受信するということですね。

それぞれの通信にはプルアップ抵抗(Rp)を使います。

通信をする際にはマスタ、スレーブと役割を分け、マスタからスレーブに対して送信、受信の指示を送ります。

LCDとは

LCD(Liquid Crystal Display)とは、液晶ディスプレイと呼ばれ、生活の様々な場面で使用されています。

今回使用するLCDはこのようなものです。

最大(16*2)文字を下の図のように表示させることができます。

文字の表示は、下のASCIIコードに従います。

例えば、1は00110001と表せます。16進数にすると0x31です。

LCDデータシート

実装

目的

LCDの画面に文字を表示させることを目的とします。

事前準備

今回参考に(ほぼやることは同じですが笑)したのはこちらのホームページです。

Osoyooの解説ページです。

スターターキットに従って多くのチュートリアルを載せてくれています。

それでは設定を始めていきましょう。

①まず設定画面からI2Cを有効にして、再起動をします。

②再起動が終了したら次のコマンドを入力してください。

$ ls /dev/*i2c*
/dev/i2c-1

デバイス名が表示されれば、設定は成功です。

③次に、スレーブアドレスを取得します。

I2Cの説明でも少し触れましたが、スレーブアドレスというものを使います。これは基本的にはメーカーで固定されています。

$ i2cdetect -y 1

スレーブアドレスが表示されます。

私と同じものを使用している場合、0x27もしくは0x3Fと表示されると思います。

これで、準備は完了です。次に、電子回路です。

電子回路図

ラズパイのピンにそのままさして構いません。(接続には最新の注意を払いましょう)

プログラム

#include < stdio.h>
#include < wiringPi.h>
#include < wiringPiI2C.h>
#include < string.h>
int LCDAddr = 0x27;//I2c address of LCD, some LCD i2c address might be 0x27
int BLEN = 0;//1--open backlight.0--close backlight
int fd;//linux file descriptor
//send an  16 bits data to LCD buffer
void write_word(int data){
    int temp = data;
    if ( BLEN == 1 )
        temp |= 0x08;
    else
        temp &= 0xF7;
    wiringPiI2CWrite(fd, temp);
}
//send control command to lcd
void send_command(int comm){
    int buf;
    // Send bit7-4 firstly
    buf = comm & 0xF0;
    buf |= 0x04;            // RS = 0, RW = 0, EN = 1
    write_word(buf);
    delay(2);
    buf &= 0xFB;            // Make EN = 0
    write_word(buf);
    // Send bit3-0 secondly
    buf = (comm & 0x0F) 
    buf |= 0x04;            // RS = 0, RW = 0, EN = 1
    write_word(buf);
    delay(2);
    buf &= 0xFB;            // Make EN = 0
    write_word(buf);
}
//send character to lcd
void send_data(int data){
    int buf;
    // Send bit7-4 firstly
    buf = data & 0xF0;
    buf |= 0x05;            // RS = 1, RW = 0, EN = 1
    write_word(buf);
    delay(2);
    buf &= 0xFB;            // Make EN = 0
    write_word(buf);
    // Send bit3-0 secondly
    buf = (data & 0x0F) 
    buf |= 0x05;            // RS = 1, RW = 0, EN = 1
    write_word(buf);
    delay(2);
    buf &= 0xFB;            // Make EN = 0
    write_word(buf);
}
//initialize the lcd
void init(){
    send_command(0x33); // Must initialize to 8-line mode at first
    delay(5);
    send_command(0x32); // Then initialize to 4-line mode
    delay(5);
    send_command(0x28); // 2 Lines & 5*7 dots
    delay(5);
    send_command(0x0C); // Enable display without cursor
    delay(5);
    send_command(0x01); // Clear Screen
    wiringPiI2CWrite(fd, 0x08);
}
//clear screen
void clear(){
    send_command(0x01); //clear Screen
}
//Print the message on the lcd
void write(int x, int y, char data[]){
    int addr, i;
    int tmp;
    if (x < 0) x = 0; if (x > 15) x = 15;
    if (y < 0) y = 0; if (y > 1)  y = 1;
    // Move cursor
    addr = 0x80 + 0x40 * y + x;
    send_command(addr);
    
    tmp = strlen(data);
    for (i = 0; i < tmp; i++){
        send_data(data[i]);
    }
}
void print_info()
{
    printf("\n");
    printf("|***************************|\n");
    printf("|    IIC 1602 LCD test      |\n");
    printf("| --------------------------|\n");
    printf("| | LCD |            | Pi   |\n");
    printf("| --------------------------|\n");
    printf("| | GND | connect to | GND  |\n");
    printf("| | VCC | connect to | 5V   |\n");
    printf("| | SDA | connect to | SDA.1|\n");
    printf("| | SCL | connect to | SCL.1|\n");
    printf("| --------------------------|\n");
    printf("|                     OSOYOO|\n");
    printf("|***************************|\n");
    printf("Program is running...\n");
    printf("Press Ctrl+C to end the program\n");
}
int main(){
    //init I2C, assign a buffer handler to variable fd
    fd = wiringPiI2CSetup(LCDAddr);
    init();
    print_info();
    write(0, 0, "Hi man.Welcome ");
    write(0, 1, "to osoyoo.com");
    delay(3000);
    clear();
    while(1){
        write(0,0,"This is Lesson13");
        write(0,1,"IIC LCD Test");
        delay(1000);
    }
    return 0;
}

サンプルプログラムをコピペしました。

ただし、スレーブアドレス(LCDAddr)は自分のデバイスのアドレスに設定してください。

実行すると…

;がなかったり、if文がおかしかったりします。エラーを修正しましょう。

再度実行すると…

画面が暗くなり、文字も表示されません...

ん~、サンプルプログラムなのになんででしょう。

しっかりプログラムの意味を読み解く必要がありそうですね。

I2Cを使ってLCDに文字を表示させる!②(C言語)」に続きをまとめてあります!

関連記事
ラズパイでSPI通信に挑戦!(理論編)| C言語

続きを見る

関連記事
ラズパイでSPI通信に挑戦!(実装編)| C言語

続きを見る

スポンサーリンク

-C言語