MSP430G2553 - LCD

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

SC1604 / SC2004

SC1604 / SC2004は、I2C通信を使用したキャラクタLCDモジュールである。
これらのLCDモジュールは、16文字×4行 (SC1604) 、または、20文字×4行 (SC2004) のテキストを表示することができる。

SC1604 / SC2004は、シンプルな構造と使いやすいインターフェースが特徴である。
マイコンと接続することで、簡単に文字を表示することができる。

  • I2C通信
    SC1604 / SC2004は、I2C通信プロトコルを使用することもできる。
    I2Cは、2本の信号線 (SCLとSDA) を使用して、マスターデバイスとスレーブデバイス間でデータを転送する同期式のシリアル通信プロトコルである。
    これにより、LCDモジュールを簡単に制御することができる。

  • アドレッシング
    各LCDモジュールには、固有のI2Cアドレスが割り当てられている。
    一般的に、SC1604 / SC2004のI2Cアドレスは0x27、または、0x3fである。
    マスターデバイスは、このアドレスを使用してLCDモジュールを特定して、通信を行う。

  • コマンドとデータ
    LCDモジュールは、コマンドとデータの2種類の情報を受信する。
    コマンドは、LCDの動作を制御するための指示 (例: 画面のクリア、カーソル位置の設定等) である。
    データは、LCDに表示される実際の文字情報である。

    マスターデバイスは、コマンドとデータを適切に送信することにより、LCDの表示を制御する。

  • 初期化シーケンス
    LCDモジュールを使用する前に、一連の初期化コマンドを送信する必要がある。
    これらのコマンドは、LCDの動作モード、表示設定、文字フォント等を設定する。
    初期化シーケンスは、LCDモジュールのデータシートに記載されている。

  • 文字の表示
    初期化後、マスターデバイスは文字データをLCDモジュールに送信することにより、文字を表示することができる。
    各文字は、ASCIIコード、または、カスタム文字コードで表される。
    LCDモジュールは、受信した文字データを表示用のRAMに格納して、画面に表示する。

  • カーソル制御
    LCDモジュールには、カーソル位置を制御するためのコマンドがある。
    これにより、文字の表示位置を指定したり、カーソルを移動させたりすることができる。

  • バックライト制御
    多くのSC1604 / SC2004モジュールは、バックライト機能を備えている。
    バックライトの制御は、別の信号線や専用のコマンドを使用して行う。



SC1602 / SC2004の文字コード

HD44780コントローラを搭載したLCDモジュールは、以下に示す文字コードセットをサポートしている。
また、内蔵キャラクタジェネレータ (CGROM) の他にも、CGRAMによりユーザが任意のパターンを定義することができる。

  • 基本ラテン文字 (英数字および一般的な記号)
    ASCIIコードの0x20〜0x7F (スペース、アルファベット、数字、一般的な記号)
  • 日本語カタカナ
    ASCII拡張セットの0xA0〜0xDF (半角カタカナ)
  • ユーザ定義文字
    8つのカスタムキャラクタ (CGRAM) を作成可能
    アドレスは0x00〜0x07


HD44780 1.png



SC2004 / GPIOピンで直接制御

SC2004と接続

以下に示すように、MSP430G2553とSC2004の接続する。

  • MSP430G2553のP1.0をSC2004のRS (Register Select) ピンに接続
  • MSP430G2553のP1.1をSC2004のE (Enable) ピンに接続
  • MSP430G2553のP1.2〜P1.5をSC2004のDB4〜DB7データピンに接続
  • SC2004のVss、RW、K (Backlight Cathode) ピンはGNDに接続
  • SC2004のVdd、A (Backlight Anode)ピンは+5Vに接続
  • SC2004のVo (Contrast Adjust) ピンは、10[kΩ]の可変抵抗を介してGNDに接続


  • LCDのリセットピンを0にする場合 (RS = 0)
    コマンドレジスタが選択されて、送信されるデータはコマンドとして解釈される。
  • LCDのリセットピンを1にする場合 (RS = 1)
    データレジスタが選択されて、送信されるデータは表示データとして解釈される


以下の例では、SC2004を制御する関数を実装して、SC2004を初期化して、表示する文字列をlcd_puts関数で送信している。
4ビットモード (8ビットモードと比較してデータの転送速度が遅くなる) でLCDと通信しており、データバスとして使用しているのはDB4〜DB7 (P1.2〜P1.5) の4本のみである。

  • void lcd_init(void)
    SC2004の初期化
  • void lcd_cmd(uint8_t cmd)
    コマンドの送信
  • void lcd_data(uint8_t data)
    文字データの送信
  • void lcd_puts(const char *s)
    文字列の表示


 #include <msp430.h>
 
 #define RS_PIN  BIT0    // P1.0
 #define E_PIN   BIT1    // P1.1
 #define DB4_PIN BIT2    // P1.2
 #define DB5_PIN BIT3    // P1.3
 #define DB6_PIN BIT4    // P1.4
 #define DB7_PIN BIT5    // P1.5
 
 void lcd_cmd(uint8_t cmd);
 void lcd_data(uint8_t data);
 void lcd_init(void);
 void lcd_puts(const char *s);
 
 int main(void)
 {
    WDTCTL = WDTPW | WDTHOLD;   // ウォッチドッグタイマを停止
 
    lcd_init();
 
    lcd_puts("Hello, MSP430G2553");
 
    while(1);
 }
 
 void lcd_init(void)
 {
    P1DIR |= RS_PIN | E_PIN | DB4_PIN | DB5_PIN | DB6_PIN | DB7_PIN;
 
    // LCDの電圧が立ち上がるまで40[mS]以上待機する必要がある
    __delay_cycles(40000);
 
    // 特定の命令を実行する前にBF(Busy Flag)をチェックしてはいけない
    // HDDまたはLCD制御の分野では、BFはデバイスが現在の命令を処理中かどうかを示すフラグ
    // BFが1の場合は命令処理中、0の場合は命令処理完了を表す
    // これは、"ある命令を送信する前にBFをチェックしてはいけない"ということを示唆している
    lcd_cmd(0x30);
	DELAY_US(4100);
 
	lcd_cmd(0x30);
	DELAY_US(100);
 
	lcd_cmd(0x30);
 
    // LCDの初期化
    lcd_cmd(0x28);  // LCDを4[ビット]モードに設定, 2 lines, 5x8フォント
    lcd_cmd(0x0C);  // ディスプレイをON, カーソルをOFF, 点滅をOFF
    lcd_cmd(0x06);  // 自動インクリメントカーソルを有効, シフト動作を無効
                    // シフト動作を有効にすると、文字を書き込むたびにディスプレイ全体が左右に移動する (この機能は、長い文字列を表示する時に使用する)
    lcd_cmd(0x01);  // ディスプレイの表示をクリア
 }
 
 void lcd_cmd(uint8_t cmd)
 {
    // RSピンを0にしてデータを送信
    // これにより、LCDはコマンドレジスタが選択された状態になり、送信されたデータをコマンドとして解釈される
    P1OUT &= ~RS_PIN;   // RS = 0 for command
 
    // 上位4[ビット]を送信
    P1OUT = (P1OUT & 0xC3) | ((cmd >> 4) & 0x3C);
    P1OUT |= E_PIN;
    P1OUT &= ~E_PIN;
 
    // 下位4[ビット]を送信
    P1OUT = (P1OUT & 0xC3) | ((cmd << 2) & 0x3C);
    P1OUT |= E_PIN;
    P1OUT &= ~E_PIN;
 
    __delay_cycles(2000);   // コマンドが実行されるまで待機 : 2[mS]
 }
 
 void lcd_data(uint8_t data)
 {
    // データレジスタが選択された状態で、lcd_data関数によりデータが送信される時、
    // LCDはそれを表示データとして解釈して、画面に文字が表示される
    P1OUT |= RS_PIN;    // RS = 1 for data
 
    // 上位4[ビット]を送信
    P1OUT = (P1OUT & 0xC3) | ((data >> 4) & 0x3C);
    P1OUT |= E_PIN;
    P1OUT &= ~E_PIN;
 
    // 下位4[ビット]を送信
    P1OUT = (P1OUT & 0xC3) | ((data << 2) & 0x3C);
    P1OUT |= E_PIN;
    P1OUT &= ~E_PIN;
 
    __delay_cycles(2000);   // データを書き込むまで待機 : 2[mS]
 }
 
 void lcd_puts(const char *s)
 {
    while(*s) {
       lcd_data(*s++);
    }
 }



SC2004 / I2C通信

ATmega328とI2C

MSP430G2553において、I2Cのシリアルクロック線(SCL)とシリアルデータ線(SDA)で一般的によく使用されるピンは、以下の通りである。
原則として、以下に示すピンをI2C通信に使用することが推奨される。
ただし、必要に応じて他のピンをUSCIモジュールに割り当てることも可能である。

  • SCL
    USCIモジュールのUCB0SCLに対応している。
    P1.6
    P3.1
  • SDA
    USCIモジュールのUCB0SDAの代替ピンである。
    P1.7
    P3.0


使用不可のピンを、以下に示す。

  • P1.0
  • P1.1
    外部クリスタル発振器に接続されているため、I2C通信には使用できない。
  • P1.5
  • P2.0
    P1.5はXT2IN、P2.0はXT2OUTとして使用される可能性があるため、I2C通信に使用する場合は注意が必要である。
  • P2.6
  • P2.7
    デバッグ用のJTAGインターフェースに使用されるため、I2C通信には使用できない。


※注意 1
ピンの割り当ては、プロジェクトの要件やPCBレイアウトに応じて柔軟に変更できるが、使用するピンが他の機能と競合しないように注意すること。

※注意 2
I2C通信を使用する場合は、プルアップ抵抗を適切に配置する必要がある。
多くのモジュールには、プルアップ抵抗が内蔵されているが、必要に応じて外部にプルアップ抵抗を追加する必要がある。

MSP430G2553の設定

以下の設定を適切に行うことにより、MSP430G2553でI2C通信を正常に動作させることができる。

  • クロック設定
    I2C通信を使用する前に、MSP430G2553のクロックを適切に設定する必要がある。
    通常、SMCLK (サブメインクロック) を使用して、UCB0CTL1レジスタのUCSSELビットでクロックソースを選択する。

  • ポートの設定
    I2C通信に使用するポート (例: P1.6とP1.7) を、I2C機能に設定する必要がある。
    P1SELレジスタとP1SEL2レジスタを適切に設定して、ピンをI2C通信用に割り当てる。

  • I2C通信の初期化
    UCB0CTL1レジスタのUCSWRSTビットをセットして、I2Cをリセット状態にする。
    その後、UCB0CTL0レジスタでI2Cのマスターモード、同期モード、7ビットアドレッシング等を設定する。
    また、UCB0BRレジスタでI2Cのクロック周波数を設定する。

  • I2Cアドレスの設定
    UCB0I2CSAレジスタで、スレーブデバイス(SC2004)のI2Cアドレスを設定する。

  • 割り込みの設定 (必要な場合)
    I2C通信の割り込みを使用する場合は、UCB0IEレジスタで適切な割り込みを有効にして、割り込みハンドラを設定する。

  • 通信エラーの処理
    I2C通信中にエラーが発生した場合、UCB0STATレジスタのエラーフラグを確認して、適切にエラー処理を行う。
    必要に応じて、I2Cの初期化やリスタートを行うこと。

  • 低電力モードの考慮
    MSP430G2553はデフォルトでは低電力モードになっている。
    そのため、I2C通信を使用する場合は、適切なタイミングでスリープモードから復帰させる必要がある。


SC2004の設定

SC2004は、I2Cスレーブデバイスである。

SC2004のデータシートを参照して、初期化シーケンスやコマンドを確認する。
一般的に、LCDに表示のためには、ファンクションセット、エントリーモード、ディスプレイのON / OFF等の設定が必要となる。

I2Cを介したデータ送信

MSP430からSC2004にデータを送信するには、I2Cのスタート条件、SC2004のスレーブアドレス、データ、ストップ条件の順に送信する。
送信データには、SC2004のコマンドやテキストデータが含まれる。

注意点

  • 電源電圧の確認
    SC2004は、5[V]電源が必要となることが多い。
    MSP430G2553は3.3[V]で動作するため、電圧レベル変換が必要になる場合がある。
    したがって、LCDモジュールに3.3[V]対応のものを使用する、または、適切な電圧レベル変換回路を追加する必要がある。

  • プルアップ抵抗の設定
    I2C通信では、SCLとSDAラインにプルアップ抵抗が必要である。
    多くのLCDモジュールには、プルアップ抵抗が内蔵されているが、必要に応じて外部にプルアップ抵抗を追加すること。
    プルアップ抵抗の値は、通常4.7[kΩ] 〜 10[kΩ]程度である。

  • 初期化シーケンスの確認
    SC2004の初期化シーケンスは、データシートに記載されている。
    初期化コマンドと各コマンドの実行後の遅延時間を確認して、プログラムで適切に実装すること。

  • 通信速度の設定
    I2C通信の速度は、MSP430G2553のクロック周波数とUCBRレジスタの設定によって決定される。
    SC2004のデータシートで推奨されている通信速度を確認し、適切に設定すること。

  • エラーハンドリング
    I2C通信では、エラーが発生する可能性がある。
    エラー状態を適切に処理して、必要に応じてリトライや初期化処理を行うこと。


スタートコンディション / ストップコンディション

スタートコンディション / ストップコンディションとは、I2C通信において、データ転送の開始と終了を示すために使用される特別な信号状態のことである。

  • スタートコンディション
    スタートコンディションは、マスターデバイスがデータ転送を開始することを示す。
    スタートコンディションでは、以下の手順が行われる。
    1. SCLがHIGHの状態で、SDAがHIGHからLOWに遷移する。
    2. この状態変化により、スレーブデバイスは通信の開始を認識する。

    スタートコンディションの後、マスターデバイスはスレーブデバイスのアドレスとデータ転送の方向 (読み込みまたは書き込み) を送信する。

  • ストップコンディション
    ストップコンディションは、マスターデバイスがデータ転送を終了することを示す。
    ストップコンディションでは、以下の手順が行われる。
    1. SCLがHIGHの状態で、SDAがLOWからHIGHに遷移する。
    2. この状態変化により、スレーブデバイスは通信の終了を認識する。

    ストップコンディションの後、バスは解放されて、他のデバイスが通信を開始できる状態になる。


I2C通信では、スタートコンディションとストップコンディションを使用して、複数のデバイス間でデータの読み書きを行う。
マスターデバイスは、スタートコンディションを生成してデータ転送を開始して、転送が完了したらストップコンディションを生成して通信を終了する。

MSP430G2553では、UCB0CTL1レジスタのUCTXSTTビットとUCTXSTPビットを操作することにより、スタートコンディションとストップコンディションを生成できる。

サンプルコード

  1. I2Cの初期化 (i2c_init)
    • ピンの設定、I2Cモードの設定、クロック周波数の設定等

  2. LCDの初期化 (lcd_init)
    • 8ビットデータ、2行表示、5x8ドットの設定
    • 表示ON、カーソルOFF、点滅OFFの設定
    • カーソル移動方向を右に設定
    • 画面クリア

  3. 文字列の表示 (lcd_print)
    • lcd_data関数を使用して文字データをLCDに送信


I2C通信では、i2c_start関数でスタートコンディション、i2c_stop関数でストップコンディションを発生させて、i2c_write関数でデータを送信している。
LCDへのコマンド送信は、lcd_cmd関数、データ送信はlcd_data関数を使用している。

 #include <msp430.h>
 #include <stdint.h>
 
 // I2Cアドレス
 #define LCD_ADDR 0x27
 // または
 // #define LCD_ADDR 0x3f
 
 // I2C関数
 void i2c_init();
 void i2c_start();
 void i2c_stop();
 void i2c_write(uint8_t data);
 
 // LCD関数
 void lcd_init();
 void lcd_cmd(uint8_t cmd);
 void lcd_data(uint8_t data);
 void lcd_print(const char *str);
 
 int main(void)
 {
    WDTCTL = WDTPW | WDTHOLD;   // ウォッチドッグタイマを停止
 
    i2c_init();                 // I2C初期化
    lcd_init();                 // LCD初期化
 
    lcd_print("Hello, MSP430"); // 文字列を表示
 
    while (1);
 }
 
 void i2c_init()
 {
    P1SEL |= BIT6 | BIT7;                  // I2C用のピン設定 (P1.6:SCL, P1.7:SDA)
    P1SEL2 |= BIT6 | BIT7;
 
    UCB0CTL1 |= UCSWRST;                   // I2Cをリセット
    UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC;  // I2Cマスター, I2Cモード, 同期モード
    UCB0CTL1 = UCSSEL_2 | UCSWRST;         // SMCLK, リセット解除
    UCB0BR0 = 12;                          // SCLクロック: 100kHz (12[MHz] / 12 = 100[kHz])
    UCB0BR1 = 0;
    UCB0I2CSA = LCD_ADDR;                  // スレーブアドレス
    UCB0CTL1 &= ~UCSWRST;                  // I2C動作開始
 }
 
 void i2c_start()
 {
    UCB0CTL1 |= UCTR;           // 送信モード
    UCB0CTL1 |= UCTXSTT;        // スタートコンディション
    while (UCB0CTL1 & UCTXSTT); // スタートコンディション完了まで待機
 }
 
 void i2c_stop()
 {
    UCB0CTL1 |= UCTXSTP;        // ストップコンディション
    while (UCB0CTL1 & UCTXSTP); // ストップコンディション完了まで待機
 }
 
 void i2c_write(uint8_t data)
 {
    UCB0TXBUF = data;           // データ送信
    while (!(UCB0IFG & UCTXIFG)); // 送信完了まで待機
 }
 
 void lcd_init()
 {
    __delay_cycles(50000);      // 50ms待機
 
    lcd_cmd(0x38);              // 8ビットデータ, 2行表示, 5x8ドット
    lcd_cmd(0x0C);              // 表示ON, カーソルOFF, 点滅OFF
    lcd_cmd(0x06);              // カーソル移動方向を右に設定
    lcd_cmd(0x01);              // 画面クリア
 
    __delay_cycles(2000);       // 2[mS]待機
 }
 
 void lcd_cmd(uint8_t cmd)
 {
    i2c_start();
    i2c_write(0x00);            // コマンドモード
    i2c_write(cmd);
    i2c_stop();
 
    __delay_cycles(2000);       // 2[mS]待機
 }
 
 void lcd_data(uint8_t data)
 {
    i2c_start();
    i2c_write(0x40);            // データモード
    i2c_write(data);
    i2c_stop();
 
    __delay_cycles(50);         // 50[uS]待機
 }
 
 void lcd_print(const char *str)
 {
    while (*str) {
       lcd_data(*str++);
    }
 }



ST7735

ハードウェア接続

  • ST7735のVCC、GND
    MSP430G2553のVCC、GNDピンに接続する。

  • ST7735のSCL、SDA
    MSP430G2553のSPIピン (UCB0SCL、UCB0SDA)に接続する。

    SPI (UCB0) のピン配置
    • UCB0SIMO (SDA) : P1.7 (14番ピン)
    • UCB0SCLK (SCL) : P1.5 (12番ピン)

  • ST7735のRESET、D/C、CS (チップセレクト)
    MSP430G2553の任意のGPIOピンに接続可能であるが、一般的に以下に示すような接続を推奨する。
    • RESET : P2.0 (8番ピン)
    • D/C (データ/コマンド) : P2.1 (9番ピン)
    • CS (チップセレクト) : P2.2 (10番ピン)

    P2.0〜P2.2は連続したピンであるため、配線が整理しやすい。
    P2.xポートのピンはデジタル入出力専用であるため、アナログ機能との競合が無い。

    P1.0〜P1.4の中から選択することも可能であるが、P1.6はクリスタル用に予約されている可能性があるため、避けることを推奨する。


SPIの設定

まず、SPIモジュール (USCI_B0) を初期化して、マスターモードで動作するように設定する。
次に、SPIのクロック速度、データ順序、クロックポラリティ等を設定する。

GPIOの設定

RESET、D/C、CSに接続したGPIOピンを出力モードに設定する。

ST7735の初期化

RESETピンをLowにした後にHighにすることにより、ST7735をリセットすることができる。

必要な初期化コマンドをSPIを通じて送信する。
これには、スリープモードの解除、カラーモードの設定、画面の向きの設定等が含まれる。

描画関数の実装

ピクセルの描画、線の描画、長方形の塗りつぶし、文字の描画等の基本的な描画関数を実装する。

描画関数内では、必要なコマンドとデータをSPIを通じてST7735に送信する。

その他

特定のコマンドや操作の後には、ディスプレイが応答するまでに一定の時間が必要な場合がある。
例えば、スリープモードからの復帰 (SLPOUTコマンド) や ディスプレイのON / OFF (DISPON / DISPOFFコマンド) の後には、数十[mS]から数百[mS]の待機が推奨されている。

これは、ディスプレイ内部の回路が安定するまでに時間が掛かるためである。
必要な待機時間は、ディスプレイのデータシートに記載されていることがある。

一方、反転表示の有効 / 無効を設定するコマンドの場合、ディスプレイがコマンドを処理するのに掛かる時間は非常に短いため、明示的な待機時間を入れる必要はない。
しかし、もし、ディスプレイの応答が遅い場合や表示の乱れが見られる場合には、短い待機時間 (数[uS]〜数[mS]) を入れることを検討すること。

コントローラの判別

TFT LCDコントローラの判別方法を以下に示す。

  • ST7735
    解像度は128x160が標準的
  • ILI9225
    解像度は176x220が標準的
  • ILI9341
    解像度は240x320が標準的


例えば、PCB上に1.8 TFTという表記がある場合は、ST7735コントローラが最も一般的に使用される。
また、ST7735コントローラはSPIインターフェースを使用する代表的なコントローラであるため、PCB上にCS、MOSI、MISO、SCKというSPIピンの表記がある可能性が高い。

その他、確認する箇所を以下に示す。

  • 基板上の表記 (解像度、型番)
  • ピン配置やインターフェースの種類
  • 物理的なサイズと解像度の組み合わせ


サンプルコード

以下の例では、描画関数を呼び出して、必要な画像やテキストをLCDに表示している。

  1. まず、ST7735の初期化関数 (ST7735_Init関数)
    GPIOの設定、リセットシーケンス、初期化コマンドの送信を行う。
  2. 描画領域を設定する関数 (ST7735_SetAddrWindow)
    描画する領域の開始と終了の列と行のアドレスを設定する。
  3. 矩形を塗りつぶす関数 (ST7735_FillRect)
    指定された座標、サイズ、色で矩形を塗りつぶす。
  4. メインプログラム
    クロックとSPIの初期化、ST7735の初期化、描画関数の呼び出しを行う。


 #include <msp430.h>
 
 // GPIOピンの定義
 #define LCD_DC_PORT     P1OUT
 #define LCD_DC_PIN      BIT0
 
 #define LCD_CS_PORT     P1OUT
 #define LCD_CS_PIN      BIT1
 
 #define LCD_RESET_PORT  P1OUT
 #define LCD_RESET_PIN   BIT2
 
 // ST7735のコマンド定義
 #define ST7735_SLPOUT   0x11  // スリープモードを解除するコマンド
 #define ST7735_COLMOD   0x3A  // カラーモードを設定するコマンド
 #define ST7735_MADCTL   0x36  // 画面の向きを設定するコマンド
 #define ST7735_DISPON   0x29  // ディスプレイをオンにするコマンド
 #define ST7735_CASET    0x2A  // 列アドレスを設定するコマンド
 #define ST7735_RASET    0x2B  // 行アドレスを設定するコマンド
 #define ST7735_RAMWR    0x2C  // メモリ書き込みコマンド
 #define ST7735_INVON    0x21  // 反転表示を有効にするコマンド
 #define ST7735_INVOFF   0x20  // 反転表示を無効にするコマンド (デフォルトでは反転表示はOFF)
                               // 反転表示を有効にする場合 : ST7735_WriteCommand(ST7735_INVON);
                               // 反転表示を無効にする場合 : ST7735_WriteCommand(ST7735_INVOFF);
 
 // カラー定義
 // 16ビットRGB565カラーフォーマット (赤:5ビット, 緑:6ビット, 青:5ビットで表現)
 #define ST7735_BLUE     0x001F
 #define ST7735_RED      0xF800
 
 // ST7735の初期化関数
 void ST7735_Init()
 {
    // GPIOの設定
    GPIO_setAsOutputPin(LCD_RESET_PORT, LCD_RESET_PIN);
    GPIO_setAsOutputPin(LCD_DC_PORT, LCD_DC_PIN);
    GPIO_setAsOutputPin(LCD_CS_PORT, LCD_CS_PIN);
 
    // リセットシーケンス
    GPIO_ResetOutputPin(LCD_RESET_PORT, LCD_RESET_PIN);
    __delay_cycles(100000);  // 100[mS]待機
    GPIO_SetOutputPin(LCD_RESET_PORT, LCD_RESET_PIN);
    __delay_cycles(100000);  // 100[mS]待機
 
    // 初期化コマンドの送信
    ST7735_WriteCommand(ST7735_SLPOUT);  // スリープモードを解除
    __delay_cycles(500000);              // 500[mS]待機
 
    ST7735_WriteCommand(ST7735_COLMOD);  // カラーモードを設定
    ST7735_WriteData(0x05);              // 16ビットカラーモード
 
    ST7735_WriteCommand(ST7735_MADCTL);  // 画面の向きを設定
    ST7735_WriteData(0x00);              // 通常の向き
 
    ST7735_WriteCommand(ST7735_DISPON);  // ディスプレイをオンにする
 }
 
 // 描画領域を設定する関数
 void ST7735_SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
 {
    ST7735_WriteCommand(ST7735_CASET);  // 列アドレス設定コマンド
    ST7735_WriteData(x0 >> 8);          // 開始列の上位8ビット
    ST7735_WriteData(x0 & 0xFF);        // 開始列の下位8ビット
    ST7735_WriteData(x1 >> 8);          // 終了列の上位8ビット
    ST7735_WriteData(x1 & 0xFF);        // 終了列の下位8ビット
 
    ST7735_WriteCommand(ST7735_RASET);  // 行アドレス設定コマンド
    ST7735_WriteData(y0 >> 8);          // 開始行の上位8ビット
    ST7735_WriteData(y0 & 0xFF);        // 開始行の下位8ビット
    ST7735_WriteData(y1 >> 8);          // 終了行の上位8ビット
    ST7735_WriteData(y1 & 0xFF);        // 終了行の下位8ビット
 
    ST7735_WriteCommand(ST7735_RAMWR);  // メモリ書き込みコマンド
 }
 
 // SPIを通じてコマンドを送信する関数
 void ST7735_WriteCommand(uint8_t cmd)
 {
    GPIO_ResetOutputPin(LCD_DC_PORT, LCD_DC_PIN);  // D/Cピンを0(コマンドモード)にする
    GPIO_ResetOutputPin(LCD_CS_PORT, LCD_CS_PIN);  // CSピンを0(選択状態)にする
    USCI_B_SPI_transmitData(USCI_B0_BASE, cmd);    // SPIを通じてコマンドを送信
    GPIO_SetOutputPin(LCD_CS_PORT, LCD_CS_PIN);    // CSピンを1(非選択状態)にする
 }
 
 // SPIを通じてデータを送信する関数
 void ST7735_WriteData(uint8_t data)
 {
    GPIO_SetOutputPin(LCD_DC_PORT, LCD_DC_PIN);    // D/Cピンを1(データモード)にする
    GPIO_ResetOutputPin(LCD_CS_PORT, LCD_CS_PIN);  // CSピンを0(選択状態)にする
    USCI_B_SPI_transmitData(USCI_B0_BASE, data);   // SPIを通じてデータを送信
    GPIO_SetOutputPin(LCD_CS_PORT, LCD_CS_PIN);    // CSピンを1(非選択状態)にする
 }
 
 // ピクセルを描画する関数
 void ST7735_DrawPixel(uint16_t x, uint16_t y, uint16_t color)
 {
    ST7735_SetAddrWindow(x, y, x, y);  // 描画領域を設定
    ST7735_WriteData(color >> 8);      // 上位8ビットのカラーデータを送信
    ST7735_WriteData(color & 0xFF);    // 下位8ビットのカラーデータを送信
 }
 
 // 矩形を塗りつぶす関数
 void ST7735_FillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color)
 {
    ST7735_SetAddrWindow(x, y, x + w - 1, y + h - 1);  // 描画領域を設定
 
    uint32_t pixels = w * h;
    while (pixels--) {
        ST7735_WriteData(color >> 8);    // 上位8ビットのカラーデータを送信
        ST7735_WriteData(color & 0xFF);  // 下位8ビットのカラーデータを送信
    }
 }
 
 int main(void)
 {
    // クロックとSPIの初期化
    WDTCTL = WDTPW | WDTHOLD;  // ウォッチドッグタイマを停止
    BCSCTL1 = CALBC1_1MHZ;     // DCOを1[MHz]に設定
    DCOCTL = CALDCO_1MHZ;
    BCSCTL2 &= ~(DIVS_3);      // SMCLK分周器をクリア
 
    // SPIの設定 (UCB0を使用)
    UCB0CTL1 |= UCSWRST;                                    // ソフトウェアリセットを有効化
    UCB0CTL0 = UCCKPH | UCMSB | UCMST | UCMODE_0 | UCSYNC;  // SPIモード0、マスターモード
    UCB0CTL1 = UCSSEL_2 | UCSWRST;                          // SMCLKを選択、ソフトウェアリセットを維持
    UCB0BR0 = 1;                                            // SPIクロックを1[MHz]に設定
    UCB0BR1 = 0;
    P1SEL |= BIT5 | BIT6 | BIT7;                            // P1.5, P1.6, P1.7をSPIピンに設定
    P1SEL2 |= BIT5 | BIT6 | BIT7;
    UCB0CTL1 &= ~UCSWRST;                                   // ソフトウェアリセットを解除
 
    // ST7735の初期化
    ST7735_Init();
 
    // 矩形を描画
    ST7735_FillRect(0, 0, 128, 160, ST7735_BLUE);           // 背景を青で塗りつぶす
    ST7735_FillRect(10, 10, 108, 140, ST7735_RED);          // 赤い矩形を描画
 
    while (1) {
        // ...略
    }
 }


実際の設計では、より複雑な描画や画像の表示、ユーザインタラクションの処理等が必要になる場合がある。
また、ST7735の詳細なデータシートを参照して、必要な初期化シーケンスやコマンドを適切に実装することが重要である。


ST7789

サンプルコード

ST7789搭載のLCDを制御する場合、基本的な手順はST7735と同様であるが、いくつかの違いがある。

また、ST7789は、SPI通信のほかにDC (データ/コマンド) ピンを使用するが、一部のデバイスではSPI通信の9ビット目を使用してデータとコマンドを区別する場合もある。
その場合は、SPIの設定と通信関数を適宜変更する必要がある。

以下の例では、上記のサンプルコードをST7789向けに修正している。

  • コマンドの変更
    ST7789では、一部の制御コマンドがST7735と異なる場合がある。
    ST7789の具体的な初期化シーケンスやコマンドについては、デバイスのデータシートを参照して適切に実装する必要がある。
 // ST7789向け制御コマンド
 #define ST7789_SLPOUT   0x11  // スリープモードを解除するコマンド
 #define ST7789_COLMOD   0x3A  // カラーモードを設定するコマンド
 #define ST7789_MADCTL   0x36  // 画面の向きを設定するコマンド
 #define ST7789_DISPON   0x29  // ディスプレイをオンにするコマンド
 #define ST7789_CASET    0x2A  // 列アドレスを設定するコマンド
 #define ST7789_RASET    0x2B  // 行アドレスを設定するコマンド
 #define ST7789_RAMWR    0x2C  // メモリ書き込みコマンド
 #define ST7789_INVON    0x21  // 反転表示を有効にするコマンド
 #define ST7789_INVOFF   0x20  // 反転表示を無効にするコマンド


  • 初期化コマンドの変更
 void ST7789_Init()
 {
    // ...略 (リセットシーケンス等は同じ)
 
    // 初期化コマンドの送信
    ST7789_WriteCommand(ST7789_SLPOUT);  // スリープモードを解除
    __delay_cycles(500000);              // 500[mS]待機
 
    ST7789_WriteCommand(ST7789_COLMOD);  // カラーモードを設定
    ST7789_WriteData(0x55);              // 16ビットカラーモード
 
    ST7789_WriteCommand(ST7789_MADCTL);  // 画面の向きを設定
    ST7789_WriteData(0x00);              // 通常の向き
 
    ST7789_WriteCommand(ST7789_INVON);   // 反転表示を有効化
 
    ST7789_WriteCommand(ST7789_DISPON);  // ディスプレイをONにする
 }


  • 解像度の変更
    ST7789は、一般的に240x320ピクセルの解像度を持つため、描画関数で使用する座標の範囲を適切に調整する必要がある。
 // 背景を青で塗りつぶし、中央に赤い矩形を描画
 ST7789_FillRect(0,   0, 240, 320, ST7789_BLUE);
 ST7789_FillRect(60, 80, 120, 160, ST7789_RED);