ご無沙汰してます。
今回ですが、STM32とバックライト付きI2C制御キャラクターディスプレイ「ACM0802C-NLW-BBW-IIC」を組み合わせて様々な文字列をディスプレイに表示させてみたので、その過程を書いていきたいと思います。
やってて色々とハマりました。
ACM0802C-NLW-BBW-IICについて
秋月電子通商で販売されている、バックライト付きの8文字x2列キャラクターディスプレイ(I2C制御タイプ)です。
通販コード:P-13519
だいたいこの手のディスプレイって本来のインターフェースは8bitパラレルだったり4bitパラレルだったりするのですが、接続線が多いと煩わしいので、ディスプレイの更新速度ではやや不利になるものの今回はI2C制御タイプにしました。
最初から怪しい匂いが・・・
このディスプレイですが、データシート上にI2C通信に関する詳細な記述がありません。
秋月の商品ページには「データシートの8ページに記載がある」旨問い合わせに回答されていますが、本当に手順しか記載がなく命令レジスタ等の記載は皆無です。
上記データシートを見ていると、4ページ目に「Contoroller IC: RW1063-0A or compatible」と記載があります。
つまり「RW1063-0A」なるディスプレイ制御ICのデータシートを入手する必要がありそうです。
RW1063-0Aデータシート入手
「これはどうしたものかなー」と思いつつRW1063-0AというICのデータシートを探していたら、同じく秋月電子通商販売の「ACM2004D-FLW-FBW-IIC」というI2C制御キャラクターディスプレイのページにRW1063-0Aのデータシートと思しきものが添付されていました。
通販コード:P-17381
これをもとに他のWebサイトでの実装例なんかも見つつ実際に文字列を表示させていきたいと思います。
追伸、「ACM2004D-FLW-FBW-IIC」のページにはArduinoのサンプルスケッチを入手することもできます。一度に表示できる文字数もACM2004D-FLW-FBW-IICのほうが多いですからこれからディスプレイを使いたい人はこちらから始めるほうが難易度は低いかもしれません。
デバイスアドレスについて
ACM0802C-NLW-BBW-IICですが、コネクタの4番、5番ピンをプルアップまたはプルダウンすることでアドレスを4通りに設定できます。(ACM0802C-NLW-BBW-IICデータシート6ページに記載)
上図のSA0、SA1がそのアドレスに相当します。つまりデバイスアドレスは16進数(2進数)で
- 0x78 (0b01111000):SA1 = 0, SA0 = 0
- 0x7A (0b01111010):SA1 = 0, SA0 = 1
- 0x7C (0b01111100):SA1 = 1, SA0 = 0
- 0x7E (0b01111110):SA1 = 1, SA0 = 1
の4通りです。
レジスタアドレス
デバイスアドレスの後に送るレジスタアドレスは2通りです(RW1063-0Aデータシート28ページに詳細記載)。
- 0x00 (0b00000000):ディスプレイに何かしらの設定を送るとき
- 0x40 (0b01000000):ディスプレイの特定箇所の文字を設定するとき
RW1063-0Aデータシート中の"Control byte"中にあるA0ビットの違いで設定します。
設定データ
設定データについてはRW1063-0Aデータシート17ページに記載があります。
ここに記載された値をレジスタアドレス0x00の後に送ることでディスプレイのオンオフや表示の消去などができます。
I2Cで制御する場合はRSやRWビットは無視します。(つまり、「Read Busy Flag and Address」の命令はI2C制御時はできません。)
AUDIYはこの命令のうち「Set DDRAM Address」にハマりました。後ほど説明します。
文字データ
一般的な半角文字はRW1063-0A内部のROMに格納されていて、少なくともカタカナ以外はレジスタアドレス0x40のあとに対応するASCIIコードを送るだけでその文字が表示されます。
例えば、小文字のaを表示させたい場合は0x40のあとに0x61(10進数97)を送ればよいです。
ふむふむ pic.twitter.com/eOE0gto723
— AUDIY (@AUDIY14) September 10, 2023
プログラミングでうまいことやれば文字列をそのまま表示できそうです。
初期化
起動後のデバイスの初期化ですが、RW1063-0Aデータシートの32ページに手順が記載されています。
待ち時間まで指定されていますね・・・
文字列の表示について
実際にSTM32マイコンでI2C制御ディスプレイを動かすブログ記事があったので参考にしましたが、制御ICが違うためか見事にハマりました。
を繰り返せば文字列が表示できるようなコードに見えますが、実際にやってみても冒頭の1文字しか表示されません。
改めてRW1063-0Aのデータシートを読んでいくと、文字列表示にとても重要なことが12~14ページに記載されていました。
詳しくはデータシートを読んでいただくとして、ざっくり言うと「文字を表示したい場所をDDRAM Addressで指定しなさい」ということです。
今回使用するACM0802C-NLW-BBW-IICは8文字、2列のディスプレイなので、初期化終了時点で1列目のアドレスは0x00 ~ 0x07、2列目のアドレスは0x40 ~ 0x47とのことです。
このアドレスの変更をRW1063-0Aデータシート17ページに記載の「Set DDRAM Address」で行うということです。
つまり順序を書くと
の2つを繰り返すことで文字列表示が実現できます。
実現した動画は以下のとおりです。
やっと文字列表示できたー pic.twitter.com/Wdl9nEPqVA
— AUDIY (@AUDIY14) September 16, 2023
ライブラリ関数の実装
いくつかのI2Cの送信について関数を作ったので解説します。
といっても設定や文字列表示に関する関数は3つです。
設定書き込み関数ACMWriteInstruction()
レジスタアドレス0x00に対し代入されたデータを送信します。
文字書き込み関数ACMPrintChar()
現在指定されているDDRAMアドレスに対し文字*strを書き込みます
やっていることはACMWriteInstruction()関数とほぼ変わりません。
※DDRAM Addressの更新は行いませんので注意してください。
文字列書き込み関数ACMPrintStr()
ディスプレイに対し入力引数LNで指定した行に文字列*strを入力します。
関数内部で行指定、文字数計算およびその文字数だけACMPrintChar()関数の繰り返しを行います。
その他にもディスプレイの初期化関数や、ディスプレイに設定されたI2Cデバイスアドレスを検索する関数を実装しています。
動かしてみる
上記リンク先の関数を組み合わせて文字列を流すプログラムを実装してみました。
ウェェェェェェイ!!!!!!!!!! pic.twitter.com/mPr1F48GGJ
— AUDIY (@AUDIY14) September 17, 2023
流れとしては
- CheckACMDeviceAddress()関数でI2Cデバイスアドレスの取得
- InitACM()関数でRW1063-0Aの初期化
- ACMPrintStr();で文字列を書き込み
- ディスプレイの表示を開始
- 1秒ごとに文字列を左にシフト
- 文字列全てをシフトし終えたら最初の状態で表示し直す
- 5と6を繰り返す
という手順です。
まとめ
ということで秋月電子通商で販売されているACM0802C-NLW-BBW-IICを使って文字列を表示させてみました。
まとめとしては
- データシートの情報が不足している
- DDRAMのアドレスの更新が文字列表示のカギ
- ACM2004D-FLW-FBW-IICから始めるほうがオススメ
です。
今回作成したドライバ(HAL使用)はGitHubにアップロードしています。
MITライセンス(2条項BSDライセンス)で公開していますのでご自由にお使いいただければと思います。
また何か進捗があればブログを更新したいと思います。