● 実験テーマ134

「aitendo_TFT2P0327表示実験-その2」
(PIC24Fトレーニング基板にてaitendoの、1.77inch color LCD「TFT2P0327-E」の表示実験をしてみました。)

■ 2022.7.27
  ・SPI転送ソースを検討。
   基本スタンスは、KM-BASIC記述を、Cに移植と考えている。


■ 2022.7.29
  ・ほぼソフト構想が出来たので(キャラクタ文字描画・漢字表示・文字列表示・画像ファイル表示は後回し)
   第一弾として基本的にCで書いた、SPI関数の部分が動くかを主にテストしたいと思う。
   テストメニューは以下のようにしよう。

  <テストメニュー>
   @ 画面全体描画(16ビットカラー各色で順次全体描画)
   A 斜め直線描画
   B 直線描画テスト(次第に小さなボックスへ)
   C 円の描画
   D (BMPイメージの表示)これは後回し


■ 2022.7.30
  ・ライブラリ含め、ソース一応必要最低限書き上げた。
   コンパイルok
   hex準備出来た。

  ・Cable Ass'y 治具を作成した。
  ・hexを書込みデバッグ開始
    @ まずは駄目。
       Clear_LCD関数で、画面が白(バックライト)から黒になるはずが、モザイク模様になっている。
       GRAMがクリアされてないようだ。
    → 調べたら、この関数の中での、レジスタ番号送信コマンドが間違っていたことに気が付く。
       0x0022(Write data to GRAM REG.)が正しい。これを、0x0020と誤記していた。
       以下のように修正
       // SendRegNo(0x0020); // レジスタ番号送信:Write data to GRAM REG.
         SendRegNo(0x0022);

    A 上記の修正で、テストメニュー@ 画面全体描画(16ビットカラー各色で順次全体描画)は
       若干描画速度が遅い感じがするが、okになる。



    → 今適当に、sclkチェンジの所にそれぞれ、1uの遅延を入れていて転送速度を、約500k(2u)としているが
       前にKM-BASICでやった時は、8MHz(0.125u)設定だったので、適当に、それぞれ入れた1uの遅延をやめてみた。
       速くはなったがまだ遅いような感じ。

    B メニューB 斜め直線描画では、
       最初の白バック・黒斜め線はokだが、黒バック・白斜め線のときの白線が途中途切れて変色して見える?
    → ロジアナ等で確認する必要あり。
    → 最初の白バック・黒斜め線も良く見ると線が途中でとぎれている風に見えng 220731


■ 2022.7.31
  ・
昨日のピクセル描画関数に問題がありそうな件追求
   以下のように修正したらどうだ・・・

<修正前>
/***********************************
* 1ピクセル表示関数
* 座標は(0,0)-(159,127) 
***********************************/
void lcd_Pixel(unsigned int Xpos, unsigned int Ypos, unsigned int color)
{
    unsigned int data= ((Xpos << 8) | Ypos); // 座標シリアルデータ生成:xxyyh

    if((Xpos<ENDCOL) && (Ypos<ENDROW)){
        SET_LCD_Cursor_Position(Xpos, Ypos);
        S6D0151_SPI_write(0x0022, data); // REG22 IS WRITE DATA TO GRAM RESISTER
    }
}

<修正後:220731>
/***********************************
* 1ピクセル表示関数
* 座標は(0,0)-(159,127) 
***********************************/
void lcd_Pixel(unsigned int Xpos, unsigned int Ypos, unsigned int color)
{
    SET_LCD_Cursor_Position(Xpos, Ypos); // ドット描画座標セット

    if((Xpos<ENDCOL) && (Ypos<ENDROW)){ // 画面範囲内かチェック
        SendStartByte(0x70); // スタートバイト(ID+RS+RW)送信:コマンド書込み
        SendRegNo(0x0022); // レジスタ番号送信:Write data to GRAM REG.
        SendStartByte(0x72); // スタートバイト(ID+RS+RW)送信:データ書込み
        SendData(color); // レジスタに書込むドットデータ送信:GRAMデータ
    }
}

  ※ この修正で、テストメニュー全てokになった。
     要は、gramにピクセルデータ(色)でなく、座標データを書込んでいたので当然駄目だった。



  ※ spi転送速度設定の為に入れているnopは削除しても動くので削除した。若干描画スピード速くなった感触。


■ 2022.8.1
  ・
BMPイメージの表示をやってみたい。
   BMPファイル構成については、実験テーマ58「PIC32MX_BMP画像表示実験」モノクロ版が参考になる。
   また、QVGA液晶サイズ:320x240dotのbmpイメージの表示テストは既に、実験テーマ81「PIC32MX_UL024TF_カラーBMP表示実験」で実施済。

   この時のテスト仕様に従って進めようと思う。
    @ イメージ表示関数は、現ライブラリの中からは除外し
       mainの中に置く。
       そして、現テストメニューの中に追加するのではなく、別プロジェクト「PIC24F_TFT2P2037_BMP_IMAGE_TEST」で進める。

    A プログラムメモリ領域に、16bitカラーbmpデータテーブルを展開。
       今回の場合、160x128dotなので、 データ本体だけで、20480word= 40960byte のプログラムメモリ領域が必要だが、
       PIC24FJ64GA002のユーザープログラムメモリ領域は、22Kwordで、現プロジェクトでは、その内の、1Kwordしか消費してないので
       ライブラリと他のプログラムを含めても何とか入りそうである。(データメモリ領域=8Kwordなので、ここには置けない)

       → 実際にデータテーブルに必要な領域は、41098byteになり、かなりギリギリだがコンパイルすると
         sisz to longのエラーになる。
         しょうがないので、128x102dotに縮小してみる。13056word 26112byte

    B BMPイメージは、16bitカラー:RGB565形式(1画素に16bitを割当てる方式・ハイカラ―と呼ばれる)の必要があるが、
       前のテストで使った大元のVGAサイズの「三共の倖田來未パチンコイメージ」
       があるので、それを128x102dotサイズにリサイズ+減色(24bit→ 16bit)すればよい。減色にはGIMPを使う。

    C そのバイナリーファイルを、C言語記述の、0x****に変換してくれるフリーソフト「Binary File Extractor」で変換すれば
       データテーブルが作成される。
       <追記:220808>
        ・私が使用した「Binary File Extractor」は「レフトアームテクノロジー」さん作成のフリーソフトであるが、hpを
         閉鎖されたようで、今はソフトをダウンロードすることが出来ませんが、
         ここにローカルに保存されてた圧縮ファイルを置きました:Binary File Extractor.zip
         これをダウンロードして、右クリックにて「すべて展開」をクリックすると、展開先の場所指定になるので適当な場所を
         指定すれば、そこに以下の2つのファイルが展開(解凍)されますので、BinExt.exeをクリックすれば起動します。
         → 実行ファイル:BinExt.exe
            ヘルプファイル:BinExt.chm(コンパイルされた HTML ヘルプ ファイル)   

  <実験結果>
   (1) 最初の結果
     以下最初のbmpイメージ描画関数

/********************************************************
* 16bitBMPカラーイメージ表示関数
* 128x102dot対応
*********************************************************/
void Glcd_Image4(void)
{
    unsigned int Xpos, Ypos;
    int ptr;

    /// BMPフォーマットのデータは、左下から右上に向かって配列されているので
    /// この順で描画すると、上下逆様の画像表示になってしまう。
    /// 右上の画素(ptr=(26250/2)-1)=13124, Xpos= 127, Ypos= 0)から下に向かって描画する必要がある。
    ptr= 13124;
    for(Ypos=0; Ypos < 102; Ypos++){
        for(Xpos=127; Xpos > -1; Xpos--){
            lcd_Pixel(Xpos, Ypos, ImageData[ptr--]);
        }
    }
}

     結果は駄目。
     左隅に2,3点ドット表示してるが他は何も表示されず。
     コメントにある実際のbmpイメージのドットデータ配列を今一熟知してないので
     再度復習してみる。

   (2) 2回目の結果
     以下2回目のbmpイメージ描画関数
     素直に、ImageData[0])のドットデータから書込んでみる。

/********************************************************
* 16bitBMPカラーイメージ表示関数
* 128x102dot対応
*********************************************************/
void Glcd_Image4(void)
{
    unsigned int Xpos, Ypos;
    int ptr;

    ptr= 0;
    for(Ypos=0; Ypos < 102; Ypos++){
        for(Xpos=0; Xpos < 128; Xpos++){
            lcd_Pixel(Xpos, Ypos, ImageData[ptr++]);
        }
    }
}

     ※ 左右上下が逆に表示された。


■ 2022.8.2
  ・
左右上下が逆に表示された問題続行。
   以下のようにしたらどうか・・・

/************************************************************
* 16bitBMPカラーイメージ表示関数
* 128x102dot対応:bmpデータ本体サイズ= 128x102dot= 13056word
*************************************************************/
void Glcd_Image4(void)
{
    unsigned int Xpos, Ypos;
    int ptr;

    /// BMPフォーマットのデータ本体は、左下から右上に向かって配列されているので
    /// この順で描画すると、上下左右逆様の画像表示になってしまう。
    /// 右上の画素(ptr=13056-1=13055, Xpos= 0, Ypos= 0)から下に向かって描画する必要がある。
    ptr= 13055;
    for(Ypos=0; Ypos < 102; Ypos++){
        for(Xpos=0; Xpos < 128; Xpos--){
            lcd_Pixel(Xpos, Ypos, ImageData[ptr--]); // ptr= 0〜 13055
        }
    }
}

  ・結果は、上下はokになったが、左右が反転(左右の位置関係は合っているが、それぞれ反転している。文字を見るとはっきり判る)

  ・bmpフォーマットの決まりで「画像の横のラインのデータは,4 の倍数に揃えなければいけない。」
   というのがある。
   現在、102dotとしているが4の倍数ではない。これを100dot(4 x 25)にして、TEST_IMAGE_3.bmp
   を作成し、それで試してみる。

  ・あと致命的なミスを発見
   Xposをディクリメントしているが、繰返し条件が致命的ミス
   誤り:for(Xpos=0; Xpos < 128; Xpos--){
   正しい:for(Xpos=127; Xpos > -1; Xpos--){
   あとマイナスになったか判断するので、unsigned int Xpos, Ypos;をint Xpos, Ypos;に修正必要

  ※ ↓

/************************************************************
* 16bitBMPカラーイメージ表示関数
* 128x100dot対応:bmpデータ本体サイズ= 128x100dot= 12800word
*************************************************************/
void Glcd_Image4(void)
{
    // unsigned int Xpos, Ypos;
    int Xpos, Ypos;
    int ptr;

    /// BMPフォーマットのデータ本体は、左下から右上に向かって配列されているので
    /// この順で描画すると、上下左右逆様の画像表示になってしまう。
    /// 右上の画素(ptr=12800-1=12799, Xpos= 0, Ypos= 0)から下に向かって描画する必要がある。  
    ptr= 12799;
    for(Ypos=0; Ypos < 100; Ypos++){
        for(Xpos=127; Xpos > -1; Xpos--){
            lcd_Pixel(Xpos, Ypos, ImageData[ptr--]); // ptr= 12799〜 0
        }
    } 
}

  ・結果は、上下はok
   左右の位置関係が逆になる。
   それぞれ反転はしてない。文字も正しい方向になっている。
   これで位置関係が治ればよいことになるが・・・・


■ 2022.8.3
  ・
左右上下が逆に表示される問題調査続行。
   BMPフォーマットのデータ本体の配列について今一理解が浅いので、ここで再度頭を整理してみた。
   ここらが関係しているのは明らかなので・・・

  <BMPフォーマットのデータ本体の配列について。web再調査>
   @ BMPフォーマットのデータ本体の配列を決めるパラメータは、情報ヘッダ部にある「biHieght」
    ※ 「biHieght」
     ・ビットマップの高さ (画素数)→ 平たく言えば「画像の高さ」(Y方向の解像度= 今回の場合、100dot)
      biHeight>0 ならばボトムアップ DIB であり, その原点は左下隅である。
      biHeight<0 ならばトップダウン DIB であり, 原点は左上隅である。

   A デフォルトでは、ビットマップデータはボトムアップ (biHeight>0) である。
      原点は左下隅である。

  ※ マップ上の原点が左下隅にあるということは、BMPテーブル全体の最終番地からデータを読み出さないといけない。
     そして描画の時の、X座標も左右逆に、Xpos= 127からディクリメントして行く必要がある。
     以下のソースで一応上手く行く。

/************************************************************
* 16bitBMPカラーイメージ表示関数
* 128x100dot対応:bmpデータ本体サイズ= 128x100dot= 12800word
*************************************************************/
void Glcd_Image4(void)
{
    int Xpos, Ypos;
    int ptr;

    /// BMPフォーマットのデータ本体は、左下から右上に向かって配列されているので
    /// この順で描画すると、上下左右逆の画像表示になってしまう。
    /// 右上の画素(ptr=12868, Xpos= 127, Ypos= 0)から下に向かって描画する必要がある。
    ptr= 12868;
    for(Ypos=0; Ypos < 100; Ypos++){
        for(Xpos=127; Xpos > -1; Xpos--){ // Xpos= 127〜 0
            lcd_Pixel(Xpos, Ypos, ImageData[ptr--]); // ptr= 12868〜 69
        }
    }
}



■ 2022.8.4
  ・
「PIC24F_TFT2P2037_TEST_2」プロジェクト開始
   まだやってない、キャラクタフォント表示実験をしてみる。

  <テストメニュー>
   @ 文字列描画
   A ASCII文字の描画

  ※ 両者共に、12x12dot ANK FONT使用


■ 2022.8.5
  ・今更だが、画面全体のクリア関数:Clear_LCD()とbasic記述の、GOSUB LCDCLRだが、
   両者共に、画面下から上に向かってクリアされる。
   クリアする前に原点を、(0,0)にしてからクリアしているが、この関数の場合のみ
   上から下にクリアしないで下から上に向かってクリアされる。
   よく見ると、右下隅が原点となってそこから左に向かい左下隅からジグザク走査で左上隅まで向かって
   全面クリアされるようである。

   ただし、ピクセル描画の場合は、素直に左上隅が(0,0)で、右下隅が(159,127)になる。

   両者共に、REG22:GRAMを書込み対象に指定するのは同じだが、
   その後画面全体のクリア関数の場合は、一気にGRAM全エリア(20480ワード= 128 x 160)を、0x0000で埋めてるが、
   ピクセル関数の場合は、1dot描画位置を指定して、そこに書込む色データを1回書込むだけの違いがある。
   この辺が関係しているのかな・・・

  ・キャラクタフォント表示実験(12x12dot ANK FONT)上手く行く。


■ 2022.8.4
  ・追加で、ちょっと小さくなるが、キャラクタフォント表示実験(8x8dot ANK FONT)も実施してみた。上手く行く。


<回路図>
 ・こちらからどうぞ
 「PIC24F_TFT2P2037-E表示実験」

<最終ソース>
 (1) PIC24F_TFT2P2037_TEST_1.c    

  <テストメニュー>
   @ 画面全体描画(16ビットカラー各色で順次全体描画)
   A 斜め直線描画
   B 直線描画テスト(次第に小さなボックスへ)

   C 円の描画

 (2) PIC24F_TFT2P2037_TEST_2.c

  <テストメニュー>
   @ 文字列描画(12x12dot ANK FONT)
   A ASCII文字の描画(12x12dot ANK FONT)
   B 文字列描画(8x8dot ANK FONT)
   C ASCII文字の描画(8x8dot ANK FONT)   

 (3) PIC24F_TFT2P2037_BMP_IMAGE_TEST.c    // 128 x 100dot 16bitカラーbmpイメージ表示

<液晶ライブラリ:制御IC= S6D0151/ SPI制御>
 S6D0151.c
 S6D0151.h

<キャラクタ・フォントデータ>
 ASCII_font.h    // 8x8dot ANK FONT
 ASCII12dot.h   // 12x12dot ANK FONT

<参考サイト>
 「Akira_FC2」さん    // 画像処理ソリューション
 「noosyteのプログラミング研究室」さん    // BMPフォーマット


← 実験テーマ1に戻る   TOP PAGEに戻る   実験テーマ135へ →