TFT LCD(ST7735)モジュールに表示を行う(fileio編)

〔skSDlib編〕 〔PICの動かせ方入門に戻る〕


前回"Arduino編"を記事にしました、今回はPIC編ですが、"fileio編"と"skSDlib編"に分けて書きます。
最初は"skSDlib"で実験していたのですがぁ.... 漢字表示はまあまあですが、BMPファイルを表示させると
遅すぎてぇMLAの"fileio"で行った次第です。
ですので"fileio"を使う場合は64Kbyte以上のPICを使います、それ以外の非力PIC用として"skSDlib"を
使った記事を書いて置きます。(このHPで使ったPICは18F26K22です)
尚、MLAの"fileio"の話は”MLAのFrameworkでfileioを試してみる”を参照してください。

秋月通商で”1.8インチ 18bitカラーTFTシールド with microSD & ジョイスティック”を買った、
(2020/03現在、秋月では販売されていない、スイッチサイエンスこちらに新バージョンがある様です。)
このシールドを使ったPIC編はこちらの"PICduinoSK"で動作させている。

《1.8インチTFT液晶ディスプレイモジュールST7735S》

1.8インチTFT液晶ディスプレイモジュールST7735S  このモジュールは、ヤッホーオークションで手に入れた、
 ST7735RST7735Sの違いが解らないのだが、
 緑色タブシールが貼ってある、上記シールドと同じ色です。

 モジュールには、"1.8TFT SPI 128*160 V1,1"と書いて有る。
 VDDピンのそばに電源レギュレータが有るのでぇ、5Vで良いのかなぁ、
 少し調べた、
 こちらのサイトに配線図、使い方、回路図等がある、参照されたし。


LCDピン
機     能
LED
バックライト、電源は3.3V、PWMで明るさを変えられるみたい
GNDに接続するとバックライトOFFです。
SCK
SPIクロックに接続するピン
SDA
SPIのデータを受けるピン
A0
送信されたデータは、コマンドかパラメータかの指定ピン
REST
ハードリセット、LOWでリセットが掛かる
CS
SPIの選択ピン(LCD側)
GND
電源および信号グランドピン
VCC
5VDCに接続する電源ピン(内蔵レギュレータで3.3Vにしている)
(3.3Vで使用する場合は裏の"J1"を半田盛りするらしい、未実験)
ここ配線しなくてもLEDからの3.3Vが回り込んで動作はしました。
このモジュールの、LCD側はSPIのデータを送るピンはありません。(チップ自体は有る様です)

SDカードと接続するピン、LCD側とは接続されていない。
LCDピン
機     能
SD_CS
SPIの選択ピン(SD側)
SD_MOSI
SPIのデータを送るピン
SD_MISO
SPIのデータを受けるピン
SD_SCK
SPIクロックに接続するピン

《PIC18F26K22》

(実験回路)

18F26K22回路図
PICは上下反対です、回路電源は3.3VでLCD電源は5.0V。
LCD付属のSDカードはメモリを挿すとノイズが酷過ぎたのであえて外付けです。
SDカードの挿入検出ピンは配線していない、ソフトで検出します。
SDカードは、秋月通商のこちらから買った物です。
SPIはMSSP1(SPI1)側を使用しています。
抵抗10KはSDを動作させる為に有ります。LCDだけなら必要は無いです。


《PIC24EP256MC202》

PIC24FJ64GB002でも実験を行った、
回路は下記と同じだがSD-CSの配線のみRB6からRB5に配線替えを行っている。

(実験回路)

24EP256MC202回路図
PICは上下反対です、回路電源は3.3VでLCD電源は5.0V。
SPIはMSSP1(SPI1)側を使用しています。


《ダウンロードプログラムについて》

↓ここからサンプルプログラムソースファイルをダウンロードして下さい。
skST7735x18.zip(18F26K22用)
skST7735x24E.zip(24EP256MC202用)
skST7735x24F.zip(24FJ64GB002用)

プログラムソースをダウンロードしたら、MPLAB Xにてプロジェクトを作成します。
以下のファイルをプロジェクトディレクトリにコピーしてプロジェクトに取込んで下さい。
次にコンパイルPIC書き込みを実行して下さい。
MPLAB(R) XC8 C Compiler Version 1.40コンパイラ
MPLAB(R) XC16 C Compiler Version 1.30コンパイラ
を使用しています。

ダウンロードしたら解凍して下さい、以下のファイル構成です。
 [fileio18]・・・・・・・・・・・MLAのfileio用ライブラリ集のディレクトリ(又は、[fileio24E])
 TFT_LCD11.c・・・・・・・TFT LCD(ST7735)の表示テストサンプルプログラム
 TFT_LCD12.c・・・・・・・TFT LCD(ST7735)の表示テストサンプルプログラム(BMPファイルを表示)
 skST7735x.c・・・・・・・・ST7735チップのTFT-LCD用関数ライブラリファイル(基本編)
 skST7735x.h・・・・・・・・ST7735チップのTFT-LCD用関数ライブラリのヘッダファイル
 skST7735x_img.c・・・ST7735チップのTFT-LCD用関数ライブラリファイル(イメージデータ出力編)
 skST7735x_img.h・・・ST7735チップのTFT-LCD用関数ライブラリのヘッダファイル
 font.h・・・・・・・・・・・・・・・キャラクタ文字(5x8)フォントファイル
            (以前、こちらで使用したファイルを使用しています)

// 以下はSDカードに入れて使用します、コンパイルには使いません。
Shinome.pdb・・・・・・・・・・・12x12漢字フォントファイル(実際のファイル名は"Shinonome_12.pdb")
            ("CJKOS Japanese Fonts"サイトの"東雲"をそのまま利用しています)
ebine.bmp・・・・・・・・・・・・・ 160x107 24bit ビットマップファイルのサンプル

 尚、18F26K22のクロックは32MHz(Fosc)を想定しています、
 24EP256MC202は60MHz(FCY)で、24FJ64GB002は32MHz(FCY)です。
 又、"[fileio18]/[fileio24E/F]"のMPLAB IDE 組込み方法はこちらを参照ください。


TFT_LCD11.c

Basic実行画像  "skST7735x.c"ファイルを使用した、
 skST7735x基本ライブラリの描画サンプルスケッチです。
 動作は3秒後に始まります。

 コンパイル(18F26K22)後のメモリ容量は、
 データが1,241byte、プログラムが4,739byteです。


TFT_LCD12.c

Image実行画像  "skST7735x_img.c"ファイルを使用した、
 ビットマップ(BMP)ファイルの描画サンプルスケッチです。
 動作は"test start"が表示され、その後3秒後に始まります。

 コンパイル(18F26K22)後のメモリ容量は、
 データが1,562byte、プログラムが37,971byteです。

SDカードに"ebine.bmp"ファイルを準備します。
このファイルは写真から160x107ビットに縮小し、BMP型式の24ビットファイルで保存した物です。
画像は、128x160以内で Windows BMP型式の24ビットファイルで作成しましょう。
画像の表示は左下から右上に表示します、これはBMPファイルがその様に記録されている為です。


skST7735x.h

ST7735チップのTFT-LCD用関数基本ライブラリのヘッダファイルです。

ST7735Rチップ用の定義とSPI接続ピン情報の定義が記述されています、変更及び追記を行う場合は
このファイルに行いましょう。
(PIC18F26K22)
#define TFT_DC     LATB4  // SPIデータのパラメータ又はコマンド選択ピン
#define TFT_CS     LATB5  // TFT_LCDモジュール選択ピン
(PIC24EP256MC202)
#define TFT_DC  LATBbits.LATB15 // SPIデータのパラメータ又はコマンド選択ピン
#define TFT_CS  LATBbits.LATB14 // TFT_LCDモジュール選択ピン
は使用するピンに応じて変更しましょう。

skST7735x.c

このライブラリは"fileio"用で記述されています。
まず利用する場合は下記行をスケッチの最初に記述します。
#include "skST7735x.h"

基本ライブラリの使い方を説明します。

LCD_begin(uint8_t dspinfo,uint8_t value)
 ディスプレイモジュールの初期化を行う処理です。
  dspinfo : LCDモジュールの情報を指定します
       現在は、"CHIP_ST7735X | DISPLAY_TYPE_1"のみしか用意されていません。
  value  : 画面の消去色指定 0 = 黒 1 = 白

 例)LCD_begin(CHIP_ST7735X | DISPLAY_TYPE_1,BLACK_SCREEN) ;

LCD_DisplayDirection(uint8_t value)
 ディスプレイの表示方向を指定する処理です。
  value : 表示方向を指定(1-4)
      1 = フレキシブルケーブル側が上方向で、原点は左上が0.0(初期状態)
      2 = フレキシブルケーブル側が下方向で、原点は左上が0.0
      3 = フレキシブルケーブル側が右方向で、原点は左上が0.0
      4 = フレキシブルケーブル側が左方向で、原点は左上が0.0

LCD_CLS(uint8_t value)
 ディスプレイの表示をクリアする処理です。
 この処理は、白か黒でのみ塗りつぶします、色を付けたい場合はFillBox()を使用。
  value : 0 = 黒(BLACK_SCREEN) 1 = 白(WHITE_SCREEN)

LCD_ColorSet(uint8_t red, uint8_t green, uint8_t blue)
 色の設定を行う処理です。
 この処理は、指定されたRGBをST7735用の色構造に変換します、
 尚、12/16/18ビットカラーのみ対応しています、その他は黒に設定されます。
 12bit(R:4 G:4 B:4) 16bit(R:5 G:6 B:5) 18bit(R:6 G:6 B:6)
 なので、初期化で設定されているカラーにより指定する上限値は変わります。
  red  : RGBで指定の赤
  green : RGBで指定の緑
  blue : RGBで指定の青

 例)18ビットカラー設定で紫色指定の場合
   LCD_ColorSet(63,0,63) ;

LCD_ReduceColorSet(uint8_t red, uint8_t green, uint8_t blue)
 RGB値(24ビット色から)の減色を行い色を設定する処理です。
 この処理は24bit(R:8 G:8 B:8)のフルカラー値から、初期化で設定されているカラーに減色し
 その値を設定する処理です。
 又、16bit色は、R(5):G(6):B(5)ビットですがG(5)にして統一します。

  red  : RGB(24ビット)で指定の赤
  green : RGB(24ビット)で指定の緑
  blue : RGB(24ビット)で指定の青

 例)12ビットカラー設定で紫色指定の場合
   LCD_ReduceColorSet(255,0,255) ;
   は、LCD_ColorSet(15,0,15) ; と同じです。

LCD_PutPixel(uint16_t xp, uint16_t yp)
 1ドット点を描画する処理です。
 モジュールにより描画範囲が異なります、ここで使用した物は128x160スクリーンです。
 他のスクリーン時は、DisplayInit()関数に追記して下さい。
  xp : ディスプレイ座標の列(横)位置
  yp : ディスプレイ座標の行(縦)位置

LCD_Circle(uint16_t xp, uint16_t yp, uint16_t radius)
 指定の円を描画する処理です。
  xp   : ディスプレイ座標の列(横)位置
  yp   : ディスプレイ座標の行(縦)位置
  radius : xp/ypを中心として、そこからの半径を指定します

LCD_FillCircle(uint16_t xp, uint16_t yp, uint16_t radius)
 指定の円エリアを指定色で塗りつぶす処理です。
 指定色とは、ColorSet()/ReduceColorSet()で行います。
  xp   : ディスプレイ座標の列(横)位置
  yp   : ディスプレイ座標の行(縦)位置
  radius : xp/ypを中心として、そこからの半径を指定します

LCD_Line(uint16_t xsp, uint16_t ysp, uint16_t xep, uint16_t yep)
 指定の線を描画する処理です。
 xsp/yspを開始点として、xep/yepを終了点とする対角線上に線を描きます。
  xsp : ディスプレイ座標の開始する列(横)位置
  ysp : ディスプレイ座標の開始する行(縦)位置
  xep : ディスプレイ座標の終了する列(横)位置
  yep : ディスプレイ座標の終了する行(縦)位置

LCD_Box(uint16_t xsp, uint16_t ysp, uint16_t xep, uint16_t yep)
 指定の四角形を描画する処理です。
 xsp/yspを開始の頂点として、xep/yepを終了の頂点とした四角形を描きます。
  xsp : ディスプレイ座標の開始する列(横)位置
  ysp : ディスプレイ座標の開始する行(縦)位置
  xep : ディスプレイ座標の終了する列(横)位置
  yep : ディスプレイ座標の終了する行(縦)位置

LCD_FillBox(uint16_t xsp, uint16_t ysp, uint16_t xep, uint16_t yep)
 指定の四角形エリアを指定色で塗りつぶす処理です。
 指定色とは、ColorSet()/ReduceColorSet()で行います。
 xsp/yspを開始の頂点として、xep/yepを終了の頂点とした四角形を塗りつぶします。
  xsp : ディスプレイ座標の開始する列(横)位置
  ysp : ディスプレイ座標の開始する行(縦)位置
  xep : ディスプレイ座標の終了する列(横)位置
  yep : ディスプレイ座標の終了する行(縦)位置

LCD_Putc(uint16_t xp, uint16_t yp, uint8_t c)
 指定された位置に1文字(5x8)描画させる処理です。
 実際の文字太さは5x7ドットで、8ドット目はスペースです。
 使うフォントは"font.h"で、0x80〜0x9Fに文字を登録可能です。
 因みに、"↑↓ΩπΣ千万円÷■〒℃±"を登録しています。
  xp : ディスプレイ座標の列(横)位置
  yp : ディスプレイ座標の行(縦)位置
  c : 表示する1文字を指定します

LC_Puts(uint16_t xp, uint16_t yp, const char *s)
 指定された位置に文字列(5x8)を描画させる処理です。
  xp : ディスプレイ座標の列(横)位置
  yp : ディスプレイ座標の行(縦)位置
  *s : 表示する文字列を指定します(文字列の最後はnullでなければなりません)

 例)0,0の位置に"108円"と18ビットカラー設定で赤色で表示する場合
     LCD_ColorSet(63,0,0) ;
     LCD_Puts(0,0,"100") ;
     LCD_Putc(18,0,0x87) ;
 又は
     char s[] = {'1','0','8',0x87,0x00} ;
     LCD_ColorSet(63,0,0) ;
     LCD_Puts(0,0,s) ;

LCD_Putc2x(uint16_t xp, uint16_t yp, uint8_t c)
 指定された位置に2倍の1文字(5x8x2)描画させる処理です。
 "font.h"を単純に2倍表示させているだけです。
  xp : ディスプレイ座標の列(横)位置
  yp : ディスプレイ座標の行(縦)位置
  c : 表示する1文字を指定します

LCD_Puts2x(uint16_t xp, uint16_t yp, const char *s)
 指定された位置に2倍の文字列(5x8x2)を描画させる処理です。
  xp : ディスプレイ座標の列(横)位置
  yp : ディスプレイ座標の行(縦)位置
  *s : 表示する文字列を指定します(文字列の最後はnullでなければなりません)

LCD_SleepCtl(uint8_t sel)
 スリープのON/OFFを行う処理です。
 復帰すればその前までの画面が表示されます、
 スリープ時は、バックライト制御ピン(LED)をOFFする機能を追加しましょう。
  sel : 0 = スリープからの復帰 1 = スリープモードにする

LCD_DisplayINV(uint8_t sel)
 ディスプレイの反転表示を切り替える処理です。
 この処理を行った時点でフレームメモリ全体(画面全体)ビットが反転して表示されます、
 即ち色が白だった場合は黒で表示します。
  sel : 0 = 反転表示OFF 1 = 反転表示ON

skST7735x_img.h

ST7735チップのTFT-LCD用関数イメージデータ出力ライブラリのヘッダファイルです。

skST7735x_img.c

このライブラリは"fileio"用で記述されています。
又、このライブラリは、SDカードを使います。
まず利用する場合は下記行をスケッチの最初に記述します。
#include "skST7735x_img.h"

イメージデータ出力ライブラリの使い方を説明します。

ans = IMG_imgInit()
 イメージ出力関連(SD)の初期化を行う処理です。
 これを呼び出す前にLCD_begin()を呼び出す必要が有ります。
 この関数はSDカードの初期化とSDカードドライバーのマウントまでを行います、
 SDカードを使用しなくなった場合、SDカードを取り出す場合はIMG_imgEnd()を呼び出します。
  ans : 0 = 正常終了
     1 = fileioライブラリ(FILEIO_Initialize)の初期化エラー
     2 = カードが検出されなかった
     3 = ドライバーがマウントされなかった

 例)LCD_begin(CHIP_ST7735X | DISPLAY_TYPE_1,BLACK_SCREEN) ;
   IMG_imgInit() ;

ans = IMG_imgEnd()
 イメージ出力関連(SD)の終了操作を行う処理
 SDカードの操作が終了した場合は必ずこの関数を呼び出します。
  ans : 0 = 正常終了  0以外は"FILEIO_ERROR_TYPE"を返します(fileio.hを参照)

ans = IMG_PutImage(uint16_t xp, uint16_t yp, const char *filename)
 BMP画像を表示させる処理です。
 Windowsの24ビットカラーのみ対応で、表示可能なスクリーンサイズ内で作成します。
  xp    : ディスプレイ座標の列(横)開始位置
  yp    : ディスプレイ座標の行(縦)開始位置
  *filename : BMPのファイル名(半角大文字 xxxxxxxx.BMP)
  ans    : 0 = 正常終了
        1 = ファイルオープンエラー(ファイルが存在しないかも)
        2 = BMPファイルでない又は、24ビットカラーでない

 例)ans = IMG_PutImage(0,0,"EBINE.BMP") ;

ans = IMG_PutcK(uint16_t xp, uint16_t yp, uint16_t c)
 指定された位置に漢字1文字(12x12)描画させる処理です。
 SDカードからフォントデータ(SHINOME.PDB)を読み出して表示させます。
  xp : ディスプレイ座標の列(横)位置
  yp : ディスプレイ座標の行(縦)位置
  c  : 漢字コード(JISコード)を指定する、'熊'なら0x3727
  ans : 0 = 正常終了
     1 = ファイルオープンエラー(ファイルが存在しないかも)

※ 漢字のJISコードを調べるには、KGK紀州技研さんのこちらをお使いください。

JISコードを調べるサイト
"漢字(日本)→JISコード"にチェック入れ、
変換元に文字列を入力後、[変換>]をクリックします。

ans = IMG_PutsK(uint16_t xp, uint16_t yp, uint16_t *s)
 指定された位置に漢字文字列(12x12)を描画させる処理です。
  xp : ディスプレイ座標の列(横)位置
  yp : ディスプレイ座標の行(縦)位置
  *s : 表示する文字列を指定します(文字列の最後はnullでなければなりません)
  ans : 0 = 正常終了
     1 = ファイルオープンエラー(ファイルが存在しないかも)

 例)0,0の位置に"くまモン"と18ビットカラー設定で赤色で表示する場合
     char s[] = {0x242F,0x245E,0x2562,0x2573,0x00} ;

     LCD_ColorSet(63,0,0) ;
     IMG_PutsK(0,0,s) ;

《fileioの設定について》

"fileio"の操作方法はこちらを参照すれば良いのですがファイルの変更点のみ書いて置きます。

・SDカードを選択するピンの指定
 "system.c"ファイルにて指定します。
 #define SDSPI_CS_PIN  LATCbits.LATC2 // SDカードのセレクト(CS)ピン(PIC18F26K22)
 #define SDSPI_CS_PIN  LATBbits.LATB6 // SDカードのセレクト(CS)ピン(24EP256MC202)

・MSSP1/MSSP2の指定
 "drv_spi_config.h"にて指定します。
 使用したい方の#define文を生かします。

・SPIの通信モードを変更したい場合
 "sd_spi.c"にて変更します。
 FILEIO_SD_SPISlowInitialize()/FILEIO_SD_MediaInitialize()の2カ所に
 spiInitData.spibus_mode = SPI_BUS_MODE_2;が有るので書き換えます。

・fileioのSPIドライバを使用したい場合(18F26K22)
 "drv_spi_pic18.c"内のDRV_SPI_Initialize()関数を直接呼び出します。
     DRV_SPI_INIT_DATA pData ;

     // SDカードの初期化を行う
     pData.channel = SPI_CHANNEL ;           // SPI1を使う
     pData.divider = 0x0 ;                   // Fosc/4
     pData.cke     = 0 ;                     // クロック位相
     pData.spibus_mode = SPI_BUS_MODE_2 ;    // SPIの転送モード
     DRV_SPI_Initialize((DRV_SPI_INIT_DATA *)&pData) ;
とこんなあんばいです。

・fileioのSPIドライバを使用したい場合(24EP256MC202)
 "drv_spi_16bit.c"内のDRV_SPI_Initialize()関数を直接呼び出します。
     DRV_SPI_INIT_DATA pData ;

     // SDカードの初期化を行う
     pData.channel = SPI_CHANNEL ;           // SPI1を使う
     pData.primaryPrescale   = 2 ;           // プライマリプリスケールは 4:1 (FCY/4)
     pData.secondaryPrescale = 7 ;           // セカンダリプリスケールは 1:1
     pData.cke     = 0 ;                     // クロック位相
     pData.spibus_mode = SPI_BUS_MODE_2 ;    // SPIの転送モード
     pData.mode    = 0 ;                     // 転送モードは8bit
     DRV_SPI_Initialize((DRV_SPI_INIT_DATA *)&pData) ;
とこんなあんばいです。

《その他》

24EP256MC202実験風景
PIC24EP256MC202使用時の実験風景です。
この実験もLCD側5.0V電源は接続していません、動作するのでぇ...
LCD側のSPI速度は15MHz辺りまで良いようなのでぇ、
FCY(60MHz)/4=15MHzで動作させたら、やっぱり表示早いですねぇ、でも動画表示は無理ですがぁ。
18F26K22時は、Fosc(32MHz)/4=8MHz、ダメもとで64MHz試せば良かったなぁ。




リンクの見直し(*1) 2020/03/25


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.