(レジ直)STM32G071でILI9341にグラフィックを表示する。(ラインバッファー)



小マイコンSTM32G071でILI9341にグラフィックを表示する。(ラインバッファー)


目的
カラー液晶のテスト


![o_cop795.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8f9a37fe-49e4-36b2-a92b-73c9a91f2a0e.jpeg)



```c++



//ili9341_linebuf_SPI_071


//ヘッダーファイル
#include <Adafruit_GFX.h>
#include "hh.h"

//定義
#define SCREEN_WIDTH  240 // OLED display width, in pixels
#define SCREEN_HEIGHT 320 // OLED display height, in pixels
NA_ST7735_P display(SCREEN_WIDTH, SCREEN_HEIGHT);


// ビットマップデータ
uint8_t databytes[8] =

{

  0b01100110,
  0b10101111,
  0b10111111,
  0b11011111,

  0b01111110,
  0b01111110,
  0b00111100,
  0b00011000

};


//初期化
void setup() {

  // I2Cアドレスは使用するディスプレイに合わせて変更する
  display.begin();

}//setup


//メインループ
void loop() {

  // 画面表示をクリア
  display.clearDisplay();

  //ビットマップの表示
  display.drawBitmap(2, 2, databytes, 8, 8,  RED);



  // テキストサイズを設定
  display.setTextSize(3);
  // テキスト色を設定
  display.setTextColor(WHITE);
  // テキストの開始位置を設定
  display.setCursor(20, 20);


  // 1行目に46を表示
  //display.println("ST7789V2");
  display.println("ILI9341");

  // 画面の左側に長方形(塗りつぶしなし)を描画
  // display.drawRect(左上x, 左上y, 幅, 高さ, 線の色)
  //display.drawRect(0, 0, 239, 59, WHITE);
  //display.drawRect(0, 0, 239, 319, WHITE);
  display.drawRect(0, 0, 239, 319, 0x0f0f);


  // 描画バッファの内容を画面に表示
  display.display();

  delay(1000); //1秒待つ


}//loop


```


hh.cpp



```c++:hh.cpp



//インクルド
#include "hh.h"
#include <Adafruit_GFX.h>


//定義
#define MAX_D_ID (2000)
//#define MAX_D_ID (2200) //f303 8.8kbyte

#define NA_ST7735_P_swap(a, b)                                                     \
  (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
//GPIOの設定1　開始
//GPIO
#define TFT_RST   A1
#define TFT_RS    3
#define TFT_CS    4
#define GPIO_RESET(s)  digitalWrite(TFT_RST,s)
#define GPIO_RS(s)     digitalWrite(TFT_RS,s)
#define GPIO_CS(s)     digitalWrite(TFT_CS,s)

#define DW    digitalWrite

#define TFT_MOSI 11
#define TFT_SCK  13
#define SPI_MOSI_HIGH() DW(11,HIGH)
#define SPI_MOSI_LOW()  DW(11,LOW)
#define SPI_SCK_HIGH()  DW(13,HIGH)
#define SPI_SCK_LOW()   DW(13,LOW)


void SPI_WRITE8(int s)
{
  for (int bit = 0, x = s; bit < 8; bit++) {
    if (x & 0x80) {
      SPI_MOSI_HIGH();
      SPI_SCK_HIGH();
      SPI_SCK_LOW();
    } else {
      SPI_MOSI_LOW();
      SPI_SCK_HIGH();
      SPI_SCK_LOW();
    }//end if
    x <<= 1;
  }//for
}//SPI_WRITE8


void SPI_WRITE8_A(int s)
{
  for (int bit = 0, x = s; bit < 8; bit++) {
    if (x & 0x80) {

      //              m C
      //      5432109876543210
      GPIOA->ODR  = GPIOA->ODR | 0b0000000010000000;

      //              m C
      //      5432109876543210
      GPIOA->ODR  = GPIOA->ODR | 0b0000000000100000;

      //              m C
      //      5432109876543210
      GPIOA->ODR  = GPIOA->ODR & 0b1111111111011111;

    } else {

      //              m C
      //      5432109876543210
      GPIOA->ODR  = GPIOA->ODR & 0b1111111101111111;

      //              m C
      //      5432109876543210
      GPIOA->ODR  = GPIOA->ODR | 0b0000000000100000;

      //              m C
      //      5432109876543210
      GPIOA->ODR  = GPIOA->ODR & 0b1111111111011111;

    }//end if
    x <<= 1;
  }//for
}//SPI_WRITE8


void NA_ST7735_P::GPIO_8BIT(uint8_t s)
{
  SPI_WRITE8(s);
} //GPIO_8BIT


//コマンドの書き込み
void NA_ST7735_P::LCD_Write_CMD(uint8_t a)
{
  GPIO_CS(0);//CS=0; 12
  GPIO_RS(0); //A0=0; 9
  GPIO_8BIT(a);//P1=a; data SPI SPI
  GPIO_CS(1);//CS=1; 12
} //LCD_Write_CMD


//データ書き込み
void NA_ST7735_P::LCD_Write_Data(uint8_t a)
{
  GPIO_CS(0);//CS=0; 12
  GPIO_RS(1); //A0=1; 9
  GPIO_8BIT(a);//P1=a; data SPI SPI
  GPIO_CS(1);//CS=1; 12
} //LCD_Write_Data


//液晶の初期化処理
void NA_ST7735_P::TXDT144TF_ST7735S_Init(void)
{

  GPIO_RESET(1);//LCD_RESET=1;
  delay(1); //Delay 1ms

  GPIO_RESET(0);//LCD_RESET=0;
  delay(1); //Delay 1ms

  GPIO_RESET(1);//LCD_RESET=1;
  delay(120); //Delay 120ms

  LCD_Write_CMD(0x01);//SOFTWARE RESET
  delay(50);

  LCD_Write_CMD(0x01);//SOFTWARE RESET
  delay(50);

  LCD_Write_CMD(0x11);//SLEEP OUT
  delay(200);

  LCD_Write_CMD(0x29);//display on
  delay(100);

  LCD_Write_CMD(0x3a);//Interface pixel format
  LCD_Write_Data(0x55);//16bit mode
  delay(100);

  LCD_Write_CMD(0x36);//RGB-RGR format
  LCD_Write_Data(0x08);//RGB mode
  delay(100);

} //TXDT144TF_ST7735S_Init


NA_ST7735_P::NA_ST7735_P(uint16_t w, uint16_t h)
  : Adafruit_GFX(w, h), buffer(NULL)

{
}


//バッファのクリア
NA_ST7735_P::~NA_ST7735_P(void) {
  if (buffer) {
    free(buffer);
    buffer = NULL;
  }
}//~NA_ST7735_P


//初期処理
bool NA_ST7735_P::begin(void) {

//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
//  if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
//    return false;


  if ((!buffer) && !(buffer = (uint8_t *)malloc(MAX_D_ID * 4)   ))
    return false;


  //バッファーのクリア
  clearDisplay();

  //ポートのモード設定　アウトプットモード
  pinMode(TFT_CS, OUTPUT);
  pinMode(TFT_RST, OUTPUT);
  pinMode(TFT_RS, OUTPUT);

  pinMode(TFT_MOSI, OUTPUT);
  pinMode(TFT_SCK , OUTPUT);


  //ポートの初期化
  GPIO_CS(1);//CS=1
  GPIO_RESET(1);//RESET=1
  GPIO_RS(0);//RS=0


  delay(500); //0.5秒待つ

  //液晶の初期化処理
  TXDT144TF_ST7735S_Init();

  //画面の書き込み開始
  //display();

  return true; // Success
}//begin


//点の表示
void NA_ST7735_P::drawPixel(int16_t x, int16_t y, uint16_t color) {
  if ((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
    // Pixel is in-bounds. Rotate coordinates if needed.
    switch (getRotation()) {
      case 1:
        NA_ST7735_P_swap(x, y);
        x = WIDTH - x - 1;
        break;
      case 2:
        x = WIDTH - x - 1;
        y = HEIGHT - y - 1;
        break;
      case 3:
        NA_ST7735_P_swap(x, y);
        y = HEIGHT - y - 1;
        break;
    }//end switch

//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
/*
    switch (color) {
      case NA_ST7735_P_WHITE:
        //0      239
        //1      238
        //2      237
        x = (WIDTH - 1) - x;
        buffer[(x / 8) +    (y * 30)  ] |=  (1 << (7 - (x & 7)));
        break;
      case NA_ST7735_P_BLACK:
        x = (WIDTH - 1) - x;
        buffer[(x / 8) +    (y * 30)  ] &= ~(1 << (7 - (x & 7)));
        break;
      case NA_ST7735_P_INVERSE:
        x = (WIDTH - 1) - x;
        buffer[(x / 8) +    (y * 30)  ] ^=  (1 << (7 - (x & 7)));
        break;
    }
    */


    //0      239
    //1      238
    //2      237
    x = (WIDTH - 1) - x;


    //ドットアイテムのカラーの設定
    buffer[ D_ID * 4 + 0] = y & 0xff; //1 0000 0000
    buffer[ D_ID * 4 + 1] = x;                                              //76P4 3210
    buffer[ D_ID * 4 + 2] = (color >> 8) & 0b11111111;                      //0000 0111
    buffer[ D_ID * 4 + 3] = (color       & 0b11011111)|((y>>3)&0b00100000); //1110 0000

    if (D_ID < (MAX_D_ID - 2)) {
      D_ID++;
    }//end if

    
  }//end if
}//drawPixel



uint16_t NA_ST7735_P::getD_ID(void) {
  return D_ID;
}



//バッファのクリア
void NA_ST7735_P::clearDisplay(void) {

//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk  
//  memset(buffer, 0, WIDTH * ((HEIGHT + 7) / 8));

  memset(buffer, 0xff, MAX_D_ID * 4 );
  D_ID=0;

  
}


bool NA_ST7735_P::getPixel(int16_t x, int16_t y) {
  if ((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
    // Pixel is in-bounds. Rotate coordinates if needed.
    switch (getRotation()) {
      case 1:
        NA_ST7735_P_swap(x, y);
        x = WIDTH - x - 1;
        break;
      case 2:
        x = WIDTH - x - 1;
        y = HEIGHT - y - 1;
        break;
      case 3:
        NA_ST7735_P_swap(x, y);
        y = HEIGHT - y - 1;
        break;
    }

    //kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
    //x = (WIDTH - 1) - x;
    //return (buffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));

    return ( 0xff );
    
  }
  return false; // Pixel out of bounds
}


uint8_t *NA_ST7735_P::getBuffer(void) {
  return buffer;
}


void NA_ST7735_P::display(void) {

  uint8_t *ptr = buffer;

  //画面の書き込み開始
  LCD_Write_CMD(0x2C); //memory write

  GPIO_RS(1); //A0=1; 9


  //画面の表示
  int     kk;
  int     fy,fx,fh,fl;
  uint8_t linebuf[WIDTH * 2];

  for (int y = 0; y < HEIGHT; y++) {

    // y
    //ラインバッファの初期化
    for (int ii = 0; ii < (WIDTH * 2); ii++) {
      linebuf[ii] = 0;
    }
    kk = 0;
    //無限ループ
    while (1) { //直線検索(全件検索)

/*
dddddddddddddddddddddddd

    buffer[ D_ID * 4 + 1] = x;                                      //76P4 3210
    buffer[ D_ID * 4 + 2] = (color >> 8) & 0xff;                    //0000 0111
    buffer[ D_ID * 4 + 3] = (color       & 0xef)+((y>>4)&0x10);     //11P0 0000


dddddddddddddddddddddddd
*/

      fy = buffer[kk * 4 + 0];
      fx = buffer[kk*4 + 1];
      fh = buffer[kk*4 + 2];
      fl = buffer[kk*4 + 3];
      if (fx == 0xff ) {break;}

      //     00P0 0000
      //    P0000 0000
      //
      fy = fy | ((fl << 3) & 0x100);

      if (fy == y) {

        //fy = buffer[kk*4 + 0];
        //fx = buffer[kk * 4 + 1];
        //fh = buffer[kk * 4 + 2];
        //fl = buffer[kk * 4 + 3];

        linebuf[ fx * 2 + 0] = fh;
        linebuf[ fx * 2 + 1] = fl & 0b11011111;

      }//end if fy

      kk++;

    }//while


    for (int x = 0; x < WIDTH; x++) {

      //---------------- 1バイト目

          //              m C
          //      5432109876543210
          GPIOB->ODR  = GPIOB->ODR & 0b1111111111011111;

          SPI_WRITE8_A(linebuf[ x * 2 + 0]);
          //SPI_WRITE8_A(0xf);

          //              m C
          //      5432109876543210
          GPIOB->ODR  = GPIOB->ODR | 0b0000000000100000;

      //---------------- 2バイト目


          //              m C
          //      5432109876543210
          GPIOB->ODR  = GPIOB->ODR & 0b1111111111011111;

          SPI_WRITE8_A(linebuf[ x * 2 + 1]);
          //SPI_WRITE8_A(0xf);


          //              m C
          //      5432109876543210
          GPIOB->ODR  = GPIOB->ODR | 0b0000000000100000;

    }//x
  }//y

}//display





```


hh.h



```c++:hh.h



#ifndef _NA_ST7735_P_H_
#define _NA_ST7735_P_H_

#include <Adafruit_GFX.h>


//kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
/*
#ifndef NO_ADAFRUIT_NA_ST7735_P_COLOR_COMPATIBILITY
#define BLACK NA_ST7735_P_BLACK     ///< Draw 'off' pixels
#define WHITE NA_ST7735_P_WHITE     ///< Draw 'on' pixels
#define INVERSE NA_ST7735_P_INVERSE ///< Invert pixels
#endif
/// fit into the SSD1306_ naming scheme
#define NA_ST7735_P_BLACK 0   ///< Draw 'off' pixels
#define NA_ST7735_P_WHITE 1   ///< Draw 'on' pixels
#define NA_ST7735_P_INVERSE 2 ///< Invert pixels
*/


#ifndef NO_ADAFRUIT_NA_ST7735_P_COLOR_COMPATIBILITY
#define BLACK NA_ST7735_P_BLACK     ///< Draw 'off' pixels
#define WHITE NA_ST7735_P_WHITE     ///< Draw 'on' pixels
#define RED NA_ST7735_P_RED     ///< Draw 'on' pixels
#endif
/// fit into the SSD1306_ naming scheme
#define NA_ST7735_P_BLACK 0x0000   ///< Draw 'off' pixels
#define NA_ST7735_P_WHITE 0xffff   ///< Draw 'on' pixels
#define NA_ST7735_P_RED 0b1111100000000000 //red



class NA_ST7735_P : public Adafruit_GFX {
  public:

    NA_ST7735_P(uint16_t w, uint16_t h);

    ~NA_ST7735_P(void);

    bool begin(void);
    void display(void);
    void clearDisplay(void);
    void drawPixel(int16_t x, int16_t y, uint16_t color);
    bool getPixel(int16_t x, int16_t y);
    uint8_t *getBuffer(void);

    void GPIO_8BIT(uint8_t s);
    void LCD_Write_CMD(uint8_t ww);
    void LCD_Write_Data(uint8_t ii);
    void TXDT144TF_ST7735S_Init(void);

    uint16_t getD_ID(void);

  protected:


    uint8_t *buffer; ///< Buffer data used for display buffer. Allocated when
    ///< begin method is called.

    uint16_t D_ID = 0;


};

#endif // _NA_ST7735_P_H_


```