電子回路わからん日記

にゃーんと言いながら電子回路いじってます

バックライト付きI2Cキャラクターディスプレイの文字列表示の修正

どもです。

寒くなって暑くなってまた寒い・・・

今回は下記ブログ記事の続きです。

audio-diy.hatenablog.com

いちいちアドレスを指定せずとも文字列を表示できるようになりましたので、その内容を記しておきたいと思います。


アドバイスは突然に

やってきました。

先日のページで参考とさせていただいた下記ブログ記事の作者の方が読んでくださったようで、

lawn-tech.jp

確かに、AUDIYが書いたディスプレイの初期化関数ではEntry Mode SetをDecrement方向にしていました。

正直、このEntry Mode Setの項ですが、I/DビットとSビットの組み合わせの動作がいまいち理解できていませんでした。

もういちど制御IC(RW1063-0A)のデータシートを読んでみます。

RW1063-0Aデータシート18ページより抜粋

このI/Dのビットが1のとき、自動でDDRAMのアドレスを増やしていくのでいちいちDDRAMのアドレスを指定することなく文字列表示ができるそうです。

この「Shift of entire display」は何を意味してるんですかね・・・?
ちなみにディスプレイのシフトに関する命令はもう一箇所にもあるのでこの違いがわかっていません(試してみるしかないか)。


いざ修正

修正箇所は2箇所です。

まずはEntry Mode Setの命令項目を増やしました。

/* 5. Entry Mode Set
*  Data (bin): 0b000001[I/D][S]
*  Data (hex): 0x0[4|5|6|7]
*
*  I/D: Increment/Decrement Bit
*  0b0: cursor/blink moves to left and DDRAM address is decreased by 1.
*  0b1: cursor/blink moves to right and DDRAM address is increased by 1.
*
*  S: Shift of Entire Display
*  0b0: Shift of entire display is not performed.
*  0b1: Shift of entire display is performed according to I/D value (I/D = "1": shift left, I/D = "0": shift right).
*/
#define ENTRY_CURSOR_LEFT  0x04 // Cursor/blink moves to left and DDRAM address is decreased by 1 : 0b00000100
#define ENTRY_DISP_RIGHT   0x05 // Right shift of entire display                                  : 0b00000101
#define ENTRY_CURSOR_RIGHT 0x06 // Cursor/blink moves to right and DDRAM address is increased by 1: 0b00000110
#define ENTRY_DISP_LEFT    0x07 // Left shift of entire display                                   : 0b00000111

 

もう一箇所、ACMPrintStr( )関数のループ内でのアドレス指定を削除しました。
その代わりにループ直前でENTRY_CURSOR_SHIFT命令を追加して確実に文字列を表示できるようにしています
多分表示は少し高速化できると思います。

/* Print 1-Line String (under 40 characters) to the ACM0802C-NLW-BLW-I2C. */
void ACMPrintStr(I2C_HandleTypeDef *hi2c, uint16_t AD, uint8_t LN, const char *str) {
    uint8_t LNx = DDRAM_LN1;
    uint8_t str_len = 0;
    uint8_t i = 0;
    const char *startstr = str;

    if (LN == 1) {
        LNx = DDRAM_LN1; // DDRAM Address: 0x80
    } else {
        LNx = DDRAM_LN2; // DDRAM Address: 0xC0
    }

    str_len = strlen(str); // Count String Length.

    if (str_len > 40) {
        str_len = 40; // String Length must be under 40 per Line.
    }

    ACMWriteInstruction(hi2c, AD, ENTRY_CURSOR_RIGHT); // Cursor/blink moves to right and DDRAM address is increased by 1.
    ACMWriteInstruction(hi2c, AD, LNx); // Specify the DDRAM Address.

    /* Print Characters in the string */
    for (i = 0; i < str_len; i++) {
        ACMPrintChar(hi2c, AD, str); // Write the character the DDRAM.
        str++;
    }

    str = startstr; // Return *str pointer to start address.
}

差分についてはGitHubを見ていただければと思います。

github.com


動作確認

ばっちりです!

またいろいろ作っていきたいです。