STM32G031でST7789V2にグラフィックを表示する。(ラインバッファー)
目的
カラー液晶のテスト
//ili9341_linebuf2_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("ST7789");
//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
//インクルド
#include "hh.h"
#include <Adafruit_GFX.h>
//定義
//#define MAX_D_ID (2000)
#define MAX_D_ID (1000)
#define NA_ST7735_P_swap(a, b) \
(((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
//GPIOの設定1 開始
#define DW digitalWrite
//#define TFT_RST A1
#define TFT_RS PA11
#define TFT_CS PA0
//#define GPIO_RESET(s) DW(TFT_RST,s)
#define GPIO_RS(s) DW(TFT_RS,s)
#define GPIO_CS(s) DW(TFT_CS,s)
#define TFT_MOSI PA12
#define TFT_SCK PB7
#define SPI_MOSI_HIGH() DW(TFT_MOSI,HIGH)
#define SPI_MOSI_LOW() DW(TFT_MOSI,LOW)
#define SPI_SCK_HIGH() DW(TFT_SCK,HIGH)
#define SPI_SCK_LOW() DW(TFT_SCK,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
//TFT_RST A1 PA1
//TFT_RS 3 PB3
//TFT_CS 4 PB5
// m C R
// 5432109876543210
#define REG_MOSI_ON GPIOA->ODR=0b0000000010000010;
// m C R
// 5432109876543210
#define REG_CLK_ON__MOSI_1 GPIOA->ODR=0b0000000010100010;
// m C R
// 5432109876543210
#define REG_MOSI_OFF GPIOA->ODR=0b0000000000000010;
// m C R
// 5432109876543210
#define REG_CLK_ON__MOSI_0 GPIOA->ODR=0b0000000000100010;
// m C R
// 5432109876543210
#define REG_CLK_OFF GPIOA->ODR=0b0000000000000010;
void SPI_WRITE8_A(int s)
{
//1
if (s & 0x80) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
//2
if (s & 0x40) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
//3
if (s & 0x20) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
//4
if (s & 0x10) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
//5
if (s & 0x08) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
//6
if (s & 0x04) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
//7
if (s & 0x02) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
//8
if (s & 0x01) {
REG_MOSI_ON;
REG_CLK_ON__MOSI_1;
REG_CLK_OFF;
} else {
REG_MOSI_OFF;
REG_CLK_ON__MOSI_0;
REG_CLK_OFF;
}//end if
}//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(0x36);//RGB-RGR format
LCD_Write_Data(0x00);//RGB mode
delay(100);
LCD_Write_CMD(0x3a);//Interface pixel format
LCD_Write_Data(0x55);//16bit mode
delay(100);
LCD_Write_CMD(0x21); //Reverse
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) {
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
//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) {
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;
}
return ( 0xff );
}
return false; // Pixel out of bounds
}
uint8_t *NA_ST7735_P::getBuffer(void) {
return buffer;
}
//TFT_RST A1 PA1
//TFT_RS 3 PB3
//TFT_CS 4 PB5
// C R
// 5432109876543210
#define REG_CS_ON GPIOB->ODR=0b0000000000101000
// C R
// 5432109876543210
#define REG_CS_OFF GPIOB->ODR=0b0000000000001000
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) { //直線検索(全件検索)
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バイト目
GPIO_CS(0);//REG_CS_OFF;
SPI_WRITE8(linebuf[ x * 2 + 0]);
GPIO_CS(1);//REG_CS_ON;
//---------------- 2バイト目
GPIO_CS(0);//REG_CS_OFF;
SPI_WRITE8(linebuf[ x * 2 + 1]);
GPIO_CS(1);//REG_CS_ON;
}//x
}//y
}//display
hh.h
#ifndef _NA_ST7735_P_H_
#define _NA_ST7735_P_H_
#include <Adafruit_GFX.h>
#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_