Featured image of post I2CディスプレイモジュールSO1602Aに文字を表示させる

I2CディスプレイモジュールSO1602Aに文字を表示させる

最終更新 2020/03/11 00:22 JST

ATmega328P内蔵のTWI(I2C)を使って「有機ELキャラクタディスプレイモジュール 16×2行 黄色」SO1602AWYB-UC-WB-U に文字を表示させた。

SO1602Aと文字数だけが違うだけで使い方が同じ
stm32とI2C接続の有機ELディスプレイSO2002AでHello worldした。
のページも併せてどうぞ。

I2Cディスプレイモジュールドライバを作る

I2C(TWI)制御フローはメーカーが用意してくれているアプリケーションノート1に書いてある。
フローチャートを参考にして書いたソースコード2

TWI(I2C)基本フロー

TWI(I2C)基本フロー

TWI(I2C)ドライバフロー

TWI(I2C)ドライバフロー

スレーブアドレスとR/Wビット

I2Cバス仕様およびユーザーマニュアル3より I2C バス仕様およびユーザーマニュアル page.13

3.1.10 スレーブアドレスとR/Wビット
データ転送の形式を下図(図9)に示します。
スタートコンディション(S)の後、スレーブアドレスが送信されます。
このアドレスは7ビット長で、8ビット目にデータ転送の方向を示すビット(R/W)が続きます。
「0」は、送信(WRITE、書き込み)を、「1」はデータのリクエスト(READ、読み出し)を示します(図10)。

出典: I2C バス仕様およびユーザーマニュアル

スタートプロセス後の最初のオクテットがスレーブアドレス このディスプレイモジュールのスレーブアドレスは011110[SA0], SA0は今回GNDに接続しているので011 1100 = 0x3C となり, 8ビット目がR/Wフラグとなっているので, アドレス0x3Cはデーターとしては0x78をバスへ送り出します。

I2CディスプレイモジュールSO1602の仕様

SO1602Aディスプレイモジュールデータフォーマット

マイクロコントローラからSO1602Aディスプレイモジュールが接続されたバスにスレーブアドレス コントロールバイト データーバイト の順番で送り出します。

コントロールバイト

CoD/C#000000
Data01000000
Cmd00000000
  • Co
    Continuation bit

  • D/C#
    Data(1) / Command(0) Selection bit

コントロールバイトは続くデーターバイトがデーターかコマンドかをディスプレイモジュールに指示しています。

データーバイト

Databyte
xxxxxxxx

これは単なる8bitデーターです

I2Cバスにコマンド送信

スレーブアドレス, 0x00,データーバイトの順にバスに送り出します。

1
2
3
4
5
6
7
8
9
//
//i2cディスプレイにコマンド送信
//
void i2c_display_send_command( uint8_t command )
{
    if (IOread_from_oled_power_on()) {  //電源が入っていないと無限ループに陥るので
        i2c_display_send( I2C_DISPLAY_ADDR, 0x00, command );
    }
}

I2Cバスにデーター送信

スレーブアドレス, 0x40,データーバイトの順にバスに送り出します。

1
2
3
4
5
6
7
8
9
//
//i2cディスプレイにデータ送信
//
void i2c_display_send_data( uint8_t data )
{
    if (IOread_from_oled_power_on()) {  //電源が入っていないと無限ループに陥るので
        i2c_display_send( I2C_DISPLAY_ADDR, 0x40, data );
    }
}

SO1602ディスプレイモジュールの使いかた

このモジュールはHD44780コントローラの使い方で使えるので
キャラクタLCDモジュールの使いかた - ELM by ChaN
を参考に書きました

SO1602Aデーターシートよりコマンド表 SO1602A-p19 SO1602A-p20 SO1602A-p21

ディスプレイモジュールに外字を登録する

レベルメーター表示の外字データー をPROGMEMに配置して

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
//
//外字登録
//
for (uint8_t code=0x00 ; code<register_characters_count ; code++) {
    //set cgram
    i2c_display_send_command (0x40 | (code<<3) | 0);    //char code 'code' and top line
    _delay_ms(1);
    //write data
    for (uint8_t n=0 ; n<8 ; n++) {
        i2c_display_send_data (pgm_read_byte(&register_characters[8*code + n]));
        _delay_ms(1);
    }
}

このループで登録してます。

付記

i2c_display.h
i2c_display.c
制御にはATMEGA328Pに内蔵されているI2C(TWI)機能を使います,I2C割り込みは難しそうなので今回は無し。

comments powered by Disqus

This website uses cookies to improve your experience.
このサイトは「Googleアナリティクス」を使用しています。
Googleアナリティクスはデータの収集のためにCookieを使用しています。


Built with Hugo
テーマ StackJimmy によって設計されています。