こんにちは。駆け出しエンジニアのまっきーです。
今回は、I2Cを使ってLCDに文字表示をさせたいと思います。
準備、用語解説
使用したもの
- RaspberryPi3B+
- I2C LCD Display(16*2)
- 1602 I2Cキャラクタ表示液晶
- 8ピンジャンパワイヤ(メス・メス)
↑8ピンでなくてもよい
上記のもの(RaspberryPiを除く)は全て下記のセットに同梱されています。
それではまず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の画面に文字を表示させることを目的とします。
事前準備
今回参考に(ほぼやることは同じですが笑)したのはこちらのホームページです。
Osoyooの解説ページです。
スターターキットに従って多くのチュートリアルを載せてくれています。
それでは設定を始めていきましょう。
①まず設定画面からI2Cを有効にして、再起動をします。

②再起動が終了したら次のコマンドを入力してください。
1 2 |
$ ls /dev/*i2c* /dev/i2c-1 |
デバイス名が表示されれば、設定は成功です。
③次に、スレーブアドレスを取得します。
I2Cの説明でも少し触れましたが、スレーブアドレスというものを使います。これは基本的にはメーカーで固定されています。
1 |
$ i2cdetect -y 1 |
スレーブアドレスが表示されます。
私と同じものを使用している場合、0x27もしくは0x3Fと表示されると思います。
これで、準備は完了です。次に、電子回路です。
電子回路図

ラズパイのピンにそのままさして構いません。(接続には最新の注意を払いましょう)
プログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
#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言語
続きを見る