ATtiny404でパラレル入力の液晶キャラクタディスプレイをUARTシリアル入力対応にしてみた
市販の液晶キャラクタディスプレイ(LCD)はマイコンから使いやすい表示器ですが,基本は8bitデータのパラレル入力です。そのため出力ピンの少ない小さなマイコンでは接続しにくいので,自分なりに使いやすくしようとパラレル入力のLCDにI2CやUARTからの変換モジュールをATtiny1604を使って自作してきました。今まで作ったモジュールは使ってしまったので,メモリは少ないですがピン数の同じATtiny404でまずはUART対応版から作ってみました。UARTモジュール付きのLCDです。100均の名刺入れに入れてみました,LCDはバックライト付きのSC1602BSLB(3.3V)で,表示データはATtiny202から送っています(^^)。LCDとモジュールの構成ですモジュールはほぼATtiny404だけみたいですね(^^;;;;;。モジュールは接続コネクタだけで固定しています,,,。配線の概略図です。LCDはHD44780(互換)コントローラで8bitパラレル入力です。4bitモードで接続するので下位4bitの入力ピンは使用しません。・レジスタセレクタ(RS):コマンドと表示データのレジスタを切り替えます・リード/ライト(R/W):LOW固定で書き込みオンリーにしています・データイネーブル(E):入力データをラッチします・データ (DB4-DB7):8bitのデータを上位4bit,下位4bitの順に入力します自作のモジュールなので複雑なことはせず,9600bps固定,また受信データは「どこ」に「何」を表示するかにしぼっています。・カーソル位置の指定やコマンド:Serial.write()・ASCII文字(7bit):Serial.print()またはSerial.write()を使って普通に書き込めます。というか,複雑なコマンドは覚えきれないので(^^;;;;;;。上の写真の表示データを送信したATtiny202側のプログラムです。// ATTiny 202 Serial test for ATtiny404 UART module for LCDvoid setup(){ delay(1000); // waiting for LCD start Serial.begin(9600); // UART 9600bps Serial.write(0x80);Serial.write(0x01); // Clear Screen delay(2); Serial.write(0);Serial.write(3); // locate 0,3 Serial.print("ATtiny 404"); // disp data Serial.write(1);Serial.write(1); // locate 1,1 Serial.print("UART LCD Test"); // disp data}void loop() { // put your main code here, to run repeatedly:} モジュール側のATtiny404のプログラムです。下に記したリンク先のATtiny1604用のものをそのまま持ってきただけで,まだまだ改良する点は多いと思いますが,まぁ動いてはいます(^^;;;;;;;;;;。☆ LCDを扱う時に気を付けている事・setupのLCDの初期化では何をやってるのか,という繰り返しがありますが,LCDコントローラを確実に8bitモードにセットしてから4bitモードにする定石となっています,,,,。・コマンドを送った後のdelayはデータシートの数値通りきっちりとっておかないと動作しなかったり,不安定だったりしますね。// LCD1602 Controll test Pro., ATtiny404 UART#define DB7 A7#define DB6 A6#define DB5 A5#define DB4 A4#define _E A2#define _RS A1void setup() { pinMode(DB7, OUTPUT ); pinMode(DB6, OUTPUT ); pinMode(DB5, OUTPUT ); pinMode(DB4, OUTPUT ); pinMode(_E, OUTPUT ); pinMode(_RS, OUTPUT ); delay (40); // Init. LCD sendU4bit(0, 0x30); // Function Set 8bit mode, 1st delayMicroseconds(38); sendU4bit(0, 0x30); // Function Set 8bit mode, 2nd delayMicroseconds(38); sendU4bit(0, 0x30); // Function Set 8bit mode, 3rd delayMicroseconds(38); sendU4bit(0, 0x20); // Function Set 4bit mode delayMicroseconds(38); sendCommand(0x28); // 4bit mode & 2line=1, font=0 sendCommand(0x06); // Cursor move increment, Shift off sendCommand(0x01); // Clear Display delay (2); sendCommand(0x0C); // Display On, Cursor off, Blink off Serial.begin(9600);}void loop() { byte recieveData1,recieveData2; recieveData1=getOnebyte(); // Recieve One Byte if (recieveData1<0x04){ // Locate Row Number recieveData2=getOnebyte(); // Column Number locate(recieveData1,recieveData2); // Set Locate }else if (recieveData1>0x1F && recieveData1<0x80){ // Ascii sendDisplay(recieveData1); }else if (recieveData1==0x80){ // Command recieveData2=getOnebyte(); sendCommand(recieveData2); }else if (recieveData1==0xC0){ // Disp recieveData2=getOnebyte(); sendDisplay(recieveData2); }}byte getOnebyte(){ byte oneByte; while (Serial.available() == 0){ } oneByte=Serial.read(); return oneByte;}void locate(byte rowNumber, byte columnNumber){ byte ddramAddress; switch (rowNumber) { case 0: ddramAddress=0; break; case 1: ddramAddress=0x40; break; case 2: ddramAddress=0x14; break; case 3: ddramAddress=0x54; break; } ddramAddress=(ddramAddress+columnNumber) | 0x80; sendCommand(ddramAddress);}void sendCommand(byte cdData){ send8bit(0, cdData); // Resistor Select =0 delayMicroseconds(38);}void sendDisplay(byte cdData){ send8bit(1, cdData); // Resistor Select =1 delayMicroseconds(38);}void send8bit(byte RS, byte cdData){ sendU4bit(RS, cdData); sendU4bit(RS, cdData*16);}void sendU4bit(byte RS, byte upper4bit){ digitalWrite(_RS, RS); digitalWrite(_E, HIGH); digitalWrite(DB7, bitRead(upper4bit,7)); digitalWrite(DB6, bitRead(upper4bit,6)); digitalWrite(DB5, bitRead(upper4bit,5)); digitalWrite(DB4, bitRead(upper4bit,4)); digitalWrite(_E, LOW); } 上のプログラムはプログラムメモリが4KBのATtiny404でも十分余裕があります。データを受け取るところをI2C版にすればI2C入力で使えるので,次の1台はそうしてみようと思っています(^^)。8ピンのマイコンでI2Cのセンサをつなぐ時などはディスプレイもI2Cだと助かりますよね。また,自作のモジュールだとライブラリのインクルードもいらないのでメモリも助かる?気はします(^^)。ま,市販でもI2Cでのシリアル入力機能を追加したものが多くみられます。ただインクルードしたライブラリでも最終的な動作はレジェンドICである日立のHD44780(互換)LCDコントローラ(パラレル入力)の様式で制御されているものが多いようですね。制作記事のページとのリンクです。・ライブラリなしでI2Cシリアル接続のキャラクタディスプレイを使う時のメモ・ATtiny1604でパラレル接続のキャラクタLCDをUART通信化するモジュールを試作してみた・安価なパラレル接続の16x2液晶キャラクタディスプレイに自作のI2Cモジュールを実装してみた