7セグLEDドライバーTM1637レビュー
今回の記事はI2Cっぽい7セグLEDドライバー【TM1637】の紹介と動作確認になります。
以前に同じような信号線タイプの7セグLEDドライバ【TM1630】というものを紹介しましたが、TM1637は同じ系統のドライバになります。
■ TM1630とTM1637の比較
TM1630 | TM1637 | |
制御LED数 | 7セグメント5段 or 8セグメント4段 | 8セグメント6段 |
輝度調整 | 8bit | 8bit |
通信インターフェース | CLK, STB, DIO | CLK, DIO |
スレーブアドレス | なし | なし |
定格電圧 | 5V | 5V |
ACK確認 | なし | あり |
(注意)3Vでも動きますが、青色ニキシー管を使用する場合は電圧降下が3Vなので5Vを使用しなければなりません。
TM1637概要
前項のTM1630との比較からわかるように【桁数が8セグメント6桁とTM1630にくらべて+2桁】されています。
また、信号線に関してもTM1630と比較してSTB線が廃止されデータとクロックのみとなっています。
以前紹介したTM1630ではデータとクロックのやり取りで1バイトづつデータおよび制御コマンドを送って、STBの立ち上げによりデータ・制御コマンドの区切りを行っていました。
つまり、TM1630側から受信の確認(ACK)は受け取ることなく一方的な通信(UDPタイプ)で表示機の制御を行っていたということになります。
一方のTM1637に関してはほぼI2Cと同じデータ制御方式を取られています(スレーブアドレスは無いのでBUS接続はできません)。
以下にデータシートから引っ張ってきた通信のタイムチャートを載せます(メーカーの透かしが入っていて見にくいですね、、、)
通信の開始はI2Cと同じくスタートコンディション(クロックがHIGHの時にデータがHIGH⇒LOW)によって開始されます。データの送信単位は1バイトです。
データの8ビット目が送信終了(第8クロックの立下り)したらTM1637チップ内部でACK信号が生成され、このACK信号によりデータがLOWレベルとなります(第9クロック)
TM1637をライブラリ無して使ってみる
動作確認として、TM1637をライブラリ無しで使用していきたいと思います。
今回はチップ単体で使用しないで4桁の7セグLEDモジュールを使用しますね。(7セグLEDの配線がめんどくさいので、、、)
イニシャライズフロー
TM1630もそうでしたが、7セグの表示方法として【固定アドレスモード】と【移動アドレスモード】の2パターンが存在します。
表示モード
- 固定アドレスモード:表示データを送るたびに7セグのアドレスを指定する
- 移動アドレスモード:表示データを送るたびに7セグのアドレスがインクリメントされる
今回は【固定アドレスモード】で進めていきたいと思います。
イニシャライズフローは以下の通りです。なお、キースキャンは使用しません。
データコマンドセッティング(Command1)
まずは、TM1637を書き込みモードに設定する必要があります。
設定マトリクスは以下になっており、B1, B0を01または11に設定することはできません。
※今回は以下の表の赤で塗りつぶした設定で進めます(0b01000100)
B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | 機能 | 備考 |
0 | 1 |
ゼロを 入れます |
0 | 0 | 書き込みまたは読み取り設定 | 書き込みモード | |||
0 | 1 | 1 | 0 | キーデータ読み取りモード | |||||
0 | 1 | 0 | アドレスモード設定 | 移動アドレスモード | |||||
0 | 1 | 1 | 固定アドレスモード | ||||||
0 | 1 | 0 | テストモード設定 | ノーマルモード | |||||
0 | 1 | 1 | テストモード |
イニシャルアドレス設定(Command2)
表示機のアドレスははB7, B6を11とすることで設定できます。今回は4桁【C0H~C3H】に表示したいと思います。(0b11000001)。
B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | ディスプレイアドレス |
1 | 1 |
ゼロを 入れます |
0 | 0 | 0 | 0 | C0H | |
1 | 1 | 0 | 0 | 0 | 1 | C1H | ||
1 | 1 | 0 | 0 | 1 | 0 | C2H | ||
1 | 1 | 0 | 0 | 1 | 1 | C3H | ||
1 | 1 | 0 | 1 | 0 | 0 | C4H | ||
1 | 1 | 0 | 1 | 0 | 1 | C5H |
表示データの設定(data)
表示データの設定はSEG1~SEG8のビットを設定(1バイト)することで任意のLEDを表示することが出来ます。なお、データの送信はLSBからMSBで送信する必要があります。
SEG1 | SEG2 | SEG3 | SEG4 | SEG5 | SEG6 | SEG7 | SEG8 |
B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
ちなみに表示機にデータを送る際井の各セグメントのビットは下記のようになっています。
(注)間のコロンは2桁目の8bit目に割り当てられているようです。
例えば、”ACEF”と表示したいときは下記のようになります。
- 0b01110111; // A
- 0b00111001; // C
- 0b01111001; // E
- 0b01110001; // F
ディスプレイコントロールコマンド
7セグLEDの輝度調整(パルス変調)と表示ON/OFFの設定になります。
B7, B6を10とすることで設定可能です。今回はパルスは2/16としました。
B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | 機能 | 備考 |
1 | 0 |
ゼロを 入れます |
0 | 0 | 0 | Pulse Width | 1/16 | ||
1 | 0 | 0 | 0 | 1 | 2/16 | ||||
1 | 0 | 0 | 1 | 0 | 4/16 | ||||
1 | 0 | 0 | 1 | 1 | 6/16 | ||||
1 | 0 | 1 | 0 | 0 | 8/16 | ||||
1 | 0 | 1 | 0 | 1 | 10/16 | ||||
1 | 0 | 1 | 1 | 0 | 12/16 | ||||
1 | 0 | 1 | 1 | 1 | 14/16 | ||||
1 | 0 | 0 | ON/OFF | ディスプレイOFF | |||||
1 | 0 | 1 | ディスプレイON |
コード(ライブラリ不使用)
今回はライブラリ不使用で通信を行います。基本的にはI2C1バイトづつの通信になります。関数としては下記を作成して制御コマンド, 表示データを送信する感じです。
関数
- スタートコンディション:CLKがHIGHの時にDIOを立ち下げる
- ストップコンディション:CLKがHIGHの時にDIOを立ち上げる
- 1バイト送信関数:1bitずつのデータ書き込み(CLKのLOWの時)&ACK確認
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 |
const uint8_t Mode= 0b01000100;//固定アドレスモード const uint8_t ADR= 0b11000000;//1桁目アドレス const uint8_t Dcont= 0b10001111;//Pulse width is set as 2/16 & ON const uint8_t num[4]= {0b01110111, 0b00111001, 0b01111001, 0b01110001};//ACEF const uint8_t CLK=12, DIO=13; void setup() { S(); writeByte(Mode); E(); //1桁目描画データ S(); writeByte(ADR); writeByte(num[0]); E(); //2桁目描画データ //8bit目はコロン S(); writeByte(ADR|1); writeByte(num[1]|0b10000000); E(); //3桁目描画データ S(); writeByte(ADR|2); writeByte(num[2]); E(); //4桁目描画データ S(); writeByte(ADR|3); writeByte(num[3]); E(); S(); writeByte(Dcont); E(); } void loop() { } //スタートコンディション void S() { pinMode(CLK, INPUT); delayMicroseconds(100); pinMode(DIO, INPUT); delayMicroseconds(100); pinMode(DIO, OUTPUT); delayMicroseconds(100); } //ストップコンディション void E() { pinMode(DIO, OUTPUT); delayMicroseconds(100); pinMode(CLK, INPUT); delayMicroseconds(100); pinMode(DIO, INPUT); delayMicroseconds(100); } bool writeByte(uint8_t b) { uint8_t data = b; // 1バイトデータ for(uint8_t i = 0; i < 8; i++) { // CLK low データの送信はクロックがLOWの時に行う pinMode(CLK, OUTPUT); delayMicroseconds(100); // ビットセット if (data & 0x01) pinMode(DIO, INPUT); else pinMode(DIO, OUTPUT); delayMicroseconds(100); // CLK high 1ビットのデータの区切り pinMode(CLK, INPUT); delayMicroseconds(100); data = data >> 1; } // ACK信号待ち pinMode(CLK, OUTPUT); pinMode(DIO, INPUT); delayMicroseconds(100); // CLKをHIGHにすることでACK解除 pinMode(CLK, INPUT); delayMicroseconds(100); uint8_t ack = digitalRead(DIO); if (ack == 0) pinMode(DIO, OUTPUT); delayMicroseconds(100); pinMode(CLK, OUTPUT); delayMicroseconds(100); return ack; } |
なお、PinModeをINPUTとOUTPUTで可変することでピンのインピーダンスを変えてHIGHとLOWを作り出しています。
pinMode
INPUT:高インピーダンスとなりHIGH論理となります
OUTPUT:低インピーダンスとなりLOW論理となります
また、ACKは8bit目のクロックの立下り時に生成され、自動的にDIOをLowレベルに立ち下げます。そして、9bit目のクロックの立ち上がり時にACKの立ち下げは解除されます。
実際に表示させてみました。
おわりに
今回はI2Cっぽい通信方式を採用しているLEDドライバTM1630の紹介でした。
実際使ってみると、かなり使いやすいですね。しかもモジュール化されているものであれば配線もしなくてすみますしとても便利です。
実際使用するときはライブラリを使用した方がもっといろいろできると思いますが、やっぱり初めはNOライブラリでという事で今回の記事でした。
ではでは~
コメント