ESP8266/ESP32 驱动ST7789屏幕

ESP8266/ESP32 驱动ST7789屏幕

本文以ESP12系列的esp8266相关多个开发板和一款ESP32开发板测试。只需要指定自己开发板具体的SPI引脚即可。

以ardunio 框架开发,本项目需要修改库文件,推荐基于platformio开发,一个项目一个第三方库目录这样不会与其他项目冲突。

安装库

  • ardunio IDE

这里以arduino ide 2.0举例,库管理搜索 搜索TFT_eSPI 找到作者为Bodmer的那个进行安装

ardunio 安装TFT_eSPI

  • 使用platformio + ardunio 框架开发的

    1.一种方式,使用pio home的界面搜索安装添加到 当前项目

    2.第二种方式:在当前项目路径打开终端执行以下命令,则会安装到本项目路径

    pio pkg install -l bodmer/TFT_eSPI

    3.第三种方式,修改ini.

    在platformio.ini里面添加以下内容,再执行构建或者 执行初始化pio init ,触发检测ini文件变化会自动下载到本项目路径

    lib_deps =
    	bodmer/TFT_eSPI@^2.4.76
    

    使用clion+platformio 环境的同学使用第三种修改ini配置的,重新初始化项目更好一些,pio init --ide clion 帮助把下载的库文件路径加到 cmake 的include中。

定义模组引脚和屏幕

找到 TFT_eSPI 库本地文件路径中的 User_Setup_Select.h文件

ardunio ide需要自己去库的路径去查找文件。

使用platformio开发,当库安装完成后本项目的.pio文件夹下有一个libdeps文件夹

在这里插入图片描述

找到User_Setup_Select.h中的 #ifndef USER_SETUP_LOADED

在其上方粘贴以下代码

  • ESP8266

    // ############# 直接在这里统一定义 屏幕和开发板/模块SPI引脚############
    #define USER_SETUP_LOADED // 使其它定义不生效
    #define ST7789_DRIVER
    // 定义SPI的引脚 以下为8266通用的数字引脚
    // #define TFT_MISO 12 // 主读从写 暂不需要
    #define TFT_MOSI 13 // 主写从读
    #define TFT_SCLK 14 // 时钟
    #define TFT_CS   15  // 片选
    #define TFT_DC    2  // 数据/命令选择线
    #define TFT_RST  -1  // 这里连RST故设置为-1
    #define TOUCH_CS -1 // 触控的片选,这里暂不使用
    
    // 宽 高
    #define TFT_WIDTH  240
    #define TFT_HEIGHT 320
    
    // 以下设置为默认暂未修改
    #define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
    #define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
    #define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
    #define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
    #define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
    #define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
    #define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
    #define SMOOTH_FONT
    #define SPI_FREQUENCY  27000000 // SPI频率
    #define SPI_TOUCH_FREQUENCY  2500000 // 字面意思 触控的SPI频率
    // ###########################################################################
    
  • ESP32 esp32并未测试多个不同的板子spi是否相等

    // ############# 直接在这里统一定义 屏幕和开发板/模块SPI引脚############
    #define USER_SETUP_LOADED // 使其它定义不生效
    #define ST7789_DRIVER
    // 定义SPI的引脚 以下为esp32 spi引脚 不确定是否通用
    // #define TFT_MISO -1 // 主读从写 暂不需要
    #define TFT_MOSI 23 // 主写从读
    #define TFT_SCLK 18 // 时钟
    #define TFT_CS   5  // 片选
    #define TFT_DC    2  // 数据/命令选择线
    #define TFT_RST  -1  // 这里连RST故设置为-1
    #define TOUCH_CS -1 // 触控的片选,这里暂不使用
    
    // 宽 高
    #define TFT_WIDTH  240
    #define TFT_HEIGHT 320
    
    // 以下设置为默认暂未修改
    #define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
    #define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
    #define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
    #define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
    #define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
    #define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
    #define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
    
    #define SMOOTH_FONT
    #define SPI_FREQUENCY  27000000 // SPI频率
    #define SPI_TOUCH_FREQUENCY  2500000 // 字面意思 触控的SPI频率
    // ###########################################################################
    

    需要注意需要注意MOSI SCLK CS 这个三个用到引脚是否为默认SPI引脚。

引脚接线

BLK 是背光开关 可以不接MCU,该脚触碰芯片的金属屏蔽罩也能熄屏

ESP8266系列开发板

ST7789引脚 ESP8266数字引脚 Wemos D1 R1 Wemos d1 r2 & mini NodeMcu 12(E/F)
GND (地) - GND GND G
VCC (可以输入3.3或者5V) - 5V/3.3V 5V/3.3V 3V
SCl (SCK时钟) 14 D13/SCK/D5 D5 D5
SDA (数据线mcu到屏幕) 13 D11/MOSI/D7 D7 D7
RES (复位线) - RST RST RST
DC (数据/命令选择线) 2 D9 D4 D4
CS (片选) 15 D10/SS D8 D8

ESP32系列开发板

ST7789引脚 ESP32数字引脚 Wemos D1 R32
GND (地) - GND
VCC (可以输入3.3或者5V) - 5V/3.3V
SCl (SCK时钟) 18 IO18
SDA (数据线mcu到屏幕) 23 IO23
RES (复位线) - RST
DC (数据/命令选择线) 2 IO2
CS (片选) 5 IO5

代码

在库文件的examples目录很多。这里找了一个分辨率匹配的时钟例子。

#include <Arduino.h>
#include <SPI.h>
#include "TFT_eSPI.h" // Hardware-specific library

#define TFT_GREY 0x5AEB

TFT_eSPI tft = TFT_eSPI();       // Invoke custom library

float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0;    // Saved H, M, S x & y multipliers
float sdeg = 0, mdeg = 0, hdeg = 0;
uint16_t osx = 120, osy = 120, omx = 120, omy = 120, ohx = 120, ohy = 120;  // Saved H, M, S x & y coords
uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0;
uint32_t targetTime = 0;                    // for next 1 second timeout

static uint8_t conv2d(const char *p); // Forward declaration needed for IDE 1.6.x
uint8_t hh = conv2d(__TIME__), mm = conv2d(__TIME__ + 3), ss = conv2d(__TIME__ + 6);  // Get H, M, S from compile time

boolean initial = 1;

void setup(void) {
    
    
    tft.init();
    tft.setRotation(0);
    //tft.fillScreen(TFT_BLACK);
    //tft.fillScreen(TFT_RED);
    //tft.fillScreen(TFT_GREEN);
    //tft.fillScreen(TFT_BLUE);
    //tft.fillScreen(TFT_BLACK);
    tft.fillScreen(TFT_GREY);

    tft.setTextColor(TFT_WHITE, TFT_GREY);  // Adding a background colour erases previous text automatically

    // Draw clock face
    tft.fillCircle(120, 120, 118, TFT_GREEN);
    tft.fillCircle(120, 120, 110, TFT_BLACK);

    // Draw 12 lines
    for (int i = 0; i < 360; i += 30) {
    
    
        sx = cos((i - 90) * 0.0174532925);
        sy = sin((i - 90) * 0.0174532925);
        x0 = sx * 114 + 120;
        yy0 = sy * 114 + 120;
        x1 = sx * 100 + 120;
        yy1 = sy * 100 + 120;

        tft.drawLine(x0, yy0, x1, yy1, TFT_GREEN);
    }

    // Draw 60 dots
    for (int i = 0; i < 360; i += 6) {
    
    
        sx = cos((i - 90) * 0.0174532925);
        sy = sin((i - 90) * 0.0174532925);
        x0 = sx * 102 + 120;
        yy0 = sy * 102 + 120;
        // Draw minute markers
        tft.drawPixel(x0, yy0, TFT_WHITE);

        // Draw main quadrant dots
        if (i == 0 || i == 180) tft.fillCircle(x0, yy0, 2, TFT_WHITE);
        if (i == 90 || i == 270) tft.fillCircle(x0, yy0, 2, TFT_WHITE);
    }

    tft.fillCircle(120, 121, 3, TFT_WHITE);

    // Draw text at position 120,260 using fonts 4
    // Only font numbers 2,4,6,7 are valid. Font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : . - a p m
    // Font 7 is a 7 segment font and only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : .
    tft.drawCentreString("clock", 120, 260, 4);

    targetTime = millis() + 1000;
}

void loop() {
    
    
    if (targetTime < millis()) {
    
    
        targetTime += 1000;
        ss++;              // Advance second
        if (ss == 60) {
    
    
            ss = 0;
            mm++;            // Advance minute
            if (mm > 59) {
    
    
                mm = 0;
                hh++;          // Advance hour
                if (hh > 23) {
    
    
                    hh = 0;
                }
            }
        }

        // Pre-compute hand degrees, x & y coords for a fast screen update
        sdeg = ss * 6;                  // 0-59 -> 0-354
        mdeg = mm * 6 + sdeg * 0.01666667;  // 0-59 -> 0-360 - includes seconds
        hdeg = hh * 30 + mdeg * 0.0833333;  // 0-11 -> 0-360 - includes minutes and seconds
        hx = cos((hdeg - 90) * 0.0174532925);
        hy = sin((hdeg - 90) * 0.0174532925);
        mx = cos((mdeg - 90) * 0.0174532925);
        my = sin((mdeg - 90) * 0.0174532925);
        sx = cos((sdeg - 90) * 0.0174532925);
        sy = sin((sdeg - 90) * 0.0174532925);

        if (ss == 0 || initial) {
    
    
            initial = 0;
            // Erase hour and minute hand positions every minute
            tft.drawLine(ohx, ohy, 120, 121, TFT_BLACK);
            ohx = hx * 62 + 121;
            ohy = hy * 62 + 121;
            tft.drawLine(omx, omy, 120, 121, TFT_BLACK);
            omx = mx * 84 + 120;
            omy = my * 84 + 121;
        }


        // Redraw new hand positions, hour and minute hands not erased here to avoid flicker
        tft.drawLine(osx, osy, 120, 121, TFT_BLACK);
        osx = sx * 90 + 121;
        osy = sy * 90 + 121;
        tft.drawLine(osx, osy, 120, 121, TFT_RED);
        tft.drawLine(ohx, ohy, 120, 121, TFT_WHITE);
        tft.drawLine(omx, omy, 120, 121, TFT_WHITE);
        tft.drawLine(osx, osy, 120, 121, TFT_RED);

        tft.fillCircle(120, 121, 3, TFT_RED);
    }
}

static uint8_t conv2d(const char *p) {
    
    
    uint8_t v = 0;
    if ('0' <= *p && *p <= '9')
        v = *p - '0';
    return 10 * v + *++p - '0';
}

可以看出主要就是利用TFT_eSPI相关函数进行绘制。

猜你喜欢

转载自blog.csdn.net/qq_26700087/article/details/127151315