ESP32-C3 VScode + PIO Arduino环境下使用Adafruit_GFX库 驱动两块0.96‘ ST7735S拼接后运行LVGL

兄弟们,写这个文章的原因是因为百度上是真找不到单片机驱动双屏的资料啊。。。研究了一两个星期的干货都塞进来了。

一、硬件

1、材料:

a.开发板:合宙的ESP32-C3真香板 RMB12.9,链接

b.屏幕:0.96寸 ST7735S驱动 80*160像素,优信的链接

2、接线:

用开发板测试通过之后,我就画了块板子来做的好看点。

两块屏都是8位SPI(带DC脚的),然后可以共用一些脚:DC、SPI_MOSI(SDA)、 SPI_SCLK(SCL),RST和SPI_CS不能共用

3、PCB的3D截个图表示一下

所以两个屏幕是一左一右的,这个后面做LVGL的双屏支持的时候需要用到

二、软件

1、驱动屏幕,Adafruit_GFX库

a.环境的搭建

VScode+PIO的环境从PIO的Libraryies里找Adafruit ST7735 and ST7789

我这边这个库的版本是1.9.3,Add to Project后可以直接使用这些个代码来验证一下硬件链接啥的

只是需要修改IO,并且将setup()和loop()函数放到其它函数的最下面去(不细说了)

我这边跑过这个例程OK之后删改的代码是这样的:

#include <Arduino.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#define TFT_CS      9        //管脚定义,左边的屏幕
#define TFT_RST     18
#define TFT_DC      19
#define TFT_SCLK    1
#define TFT_MOSI    0

#define TFT_CS2     5        //管脚定义,右边的屏幕
#define TFT_RST2    7
#define TFT_DC2     19
#define TFT_SCLK2   1
#define TFT_MOSI2   0

#define BL_EN   2

//简单粗暴的双屏定义
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
Adafruit_ST7735 tft2 = Adafruit_ST7735(TFT_CS2, TFT_DC2, TFT_MOSI2, TFT_SCLK2, TFT_RST2);

void setup(){
    pinMode(BL_EN,OUTPUT);
    digitalWrite(BL_EN,LOW);          //打开背光

    tft.initR(INITR_MINI160x80);      // Init ST7735S chip, black tab
    tft.setRotation(3);                //旋转屏幕
    tft2.initR(INITR_MINI160x80);      // Init ST7735S chip, black tab
    tft2.setRotation(1);               //旋转屏幕

    tft.fillRect(0,0,160,80,ST77XX_RED);
    tft2.fillRect(0,0,160,80,ST77XX_GREEN);
    
    tft.invertDisplay(true);        //两个屏幕反色
    tft2.invertDisplay(true);
}
void loop(){
}

b.问题的解决

如果你跟我使用的是一样的屏幕的话,就会看到写了红色的屏幕亮的是蓝色,写了绿色的屏幕却正常显示绿色。

如果你跟我使用的不是一样的屏幕,可能会看到写了红色的屏幕亮的是黄色,写了绿色的屏幕显示的是紫红色,那请你将 tft.invertDisplay(true);的true改为false,因为你不需要反色。

好了,如果你的屏幕与我一样,那很容易地,就能分析到:代码中颜色是RGB的顺序,而屏幕的颜色所需要的是BGR的顺序。

首先从main.cpp的tft.setRotation(3);的函数跳进去,从里面的四个case中可以看到RGB与GRB的字样,很显然代码走了RGB这条路,我们现在需要让他走GRB的路,我使用的方法是注释掉if...else...然后直接把原本else里的代码拿出来,如下:

然后我们烧录一下,就会发现颜色已经正常了。

然后烧录一下如下代码:

#include <Arduino.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#define TFT_CS      9        //管脚定义,左边的屏幕
#define TFT_RST     18
#define TFT_DC      19
#define TFT_SCLK    1
#define TFT_MOSI    0

#define TFT_CS2     5       //管脚定义,右边的屏幕
#define TFT_RST2    7
#define TFT_DC2     19
#define TFT_SCLK2   1
#define TFT_MOSI2   0

#define BL_EN   2

//简单粗暴的双屏定义
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
Adafruit_ST7735 tft2 = Adafruit_ST7735(TFT_CS2, TFT_DC2, TFT_MOSI2, TFT_SCLK2, TFT_RST2);

void setup(){
    pinMode(BL_EN,OUTPUT);
    digitalWrite(BL_EN,LOW);          //打开背光

    tft.initR(INITR_MINI160x80);      // Init ST7735S chip, black tab
    tft.setRotation(3);                //旋转屏幕
    tft2.initR(INITR_MINI160x80);      // Init ST7735S chip, black tab
    tft2.setRotation(1);               //旋转屏幕

    tft.fillRect(0,0,160,80,ST77XX_WHITE);
    tft2.fillRect(0,0,160,80,ST77XX_WHITE);

    tft.drawLine(0,0,159,0,ST77XX_BLUE);        //第一块屏幕最顶部画一条线-蓝色
    tft.drawLine(0,1,159,1,ST77XX_YELLOW);      //第一块屏幕第二排像素画一条线-黄色
    tft.drawLine(0,2,159,2,ST77XX_GREEN);      //第一块屏幕第三排像素画一条线-绿色

    tft2.drawLine(0,0,0,79,ST77XX_BLUE);      //第二块屏幕最左侧那一列的像素画一条线-蓝色
    tft2.drawLine(1,0,1,79,ST77XX_YELLOW);      //第二块屏幕最左侧倒数第二列的像素画一条线-黄色
    tft2.drawLine(2,0,2,79,ST77XX_GREEN);      //第二块屏幕最左侧倒数第二列的像素画一条线-绿色
    
    tft.invertDisplay(true);        //两个屏幕反色
    tft2.invertDisplay(true);
}
void loop(){
}

这只是在刷全屏之后画几条线,注意37~43的注释,烧录完这个代码之后断电再重新上电,会发现有几条线理应刷上来的却没有显示。并且屏幕的下方和右侧有杂色点。

这是因为屏幕被偏移了,仔细看看可以确定屏幕被左移了1个像素,被上移了2个像素。(看不太清,可能我说反了)

解决方法是:从setup()里的tft.initR(INITR_MINI160x80);跳进去,改这两行:

这两行是x和y的偏移,改了之后屏幕就对准了。

2、LVGL移植

VScode+PIO的环境从PIO的Libraryies里找LVGL

然后建议大家第一次用类似GUI的,或是英文不太好的,选用8.2或更低的版本,因为我在百度找了一圈,中文教程做的好的应该只有百问网,百问网现在还没有汉化8.3版本的文档,百问网LVGL8.2版本文档汉化网址

LVGL是这样的,B站很多视频是跑他的Demo,LVGL的Demo也好,主体的源码也好,都是分开的,上面这个只是添加了LVGL的主体源码进来。然后LVGL有个特点是它的配置文件一开始是没配置好的,所以需要这样操作:

在Vscode左侧找到.pio\libdeps\esp32-c3-devkitm-2(这个可能与你不一样)\lvgl找到lv_conf_template.h文件,复制它并粘贴到.pio\libdeps\esp32-c3-devkitm-2(这个可能与你不一样)目录下。 然后改名成lv_conf.h (就是把_template删掉),如图:

不要放到lvgl的文件夹里哈,不然编译会报错

然后把lv_conf.h的第15行 #if 0改成#if 1,

把第88行的#define LV_TICK_CUSTOM 0 改成#define LV_TICK_CUSTOM 1。

然后保存好,main.cpp里代码写成这样:

#include <Arduino.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <lvgl.h>           //调用LVGL

#define TFT_WIDTH 320       //LVGL认为的屏幕大小
#define TFT_HEIGHT 80

static lv_disp_draw_buf_t draw_buf;    //定义显示器变量
static lv_color_t buf[TFT_WIDTH * 20]; //定义刷新缓存
static lv_color_t buf2[TFT_WIDTH * 20]; //定义刷新缓存

#define TFT_CS      9        //管脚定义,左边的屏幕
#define TFT_RST     18
#define TFT_DC      19
#define TFT_SCLK    1
#define TFT_MOSI    0

#define TFT_CS2     5       //管脚定义,右边的屏幕
#define TFT_RST2    7
#define TFT_DC2     19
#define TFT_SCLK2   1
#define TFT_MOSI2   0

#define BL_EN   2

//简单粗暴的双屏定义
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
Adafruit_ST7735 tft2 = Adafruit_ST7735(TFT_CS2, TFT_DC2, TFT_MOSI2, TFT_SCLK2, TFT_RST2);


void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)     //LVGL用来调用显示库的函数,所以不同的显示库这个函数的内容不同
{
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);
    //跨屏幕操作
    if(area->x1 < 160) tft2.drawRGBBitmap(area->x1, area->y1,(uint16_t *)&(color_p->full),w, h);
    if(area->x2 >= 160) tft1.drawRGBBitmap(area->x1-160, area->y1,(uint16_t *)&(color_p->full),w, h);
    lv_disp_flush_ready(disp); //调用区域填充颜色函数
}

void setup(){
    pinMode(BL_EN,OUTPUT);
    digitalWrite(BL_EN,LOW);          //打开背光

    tft.initR(INITR_MINI160x80);      // Init ST7735S chip, black tab
    tft.setRotation(3);                //旋转屏幕
    tft2.initR(INITR_MINI160x80);      // Init ST7735S chip, black tab
    tft2.setRotation(1);               //旋转屏幕
    
    tft.invertDisplay(true);        //两个屏幕反色
    tft2.invertDisplay(true);

    
    lv_init();
    lv_disp_draw_buf_init(&draw_buf, buf, buf2, TFT_WIDTH * 20);
    
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    
    disp_drv.hor_res = TFT_WIDTH;
    disp_drv.ver_res = TFT_HEIGHT;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    static lv_disp_t* disp1 = lv_disp_drv_register(&disp_drv);          //初始化好显示屏的区域

    lv_obj_set_style_bg_color(lv_scr_act(),lv_color_hex(0x000000),0);   //改个黑色的背景色

    lv_obj_t *label_1 = lv_label_create(lv_scr_act());                  //建立一个标签对象
    lv_label_set_text(label_1, "Display left:\r\nHello word");          //给他打个字
    lv_obj_align(label_1, LV_ALIGN_CENTER,-80,0);                       //设置位置在居中左移80的位置,这样就是左边屏幕的中间了
    lv_obj_set_style_text_font(label_1,&lv_font_montserrat_14,0);        //在没修改的情况下只有这个字体能用,如果报错就注释掉
    lv_obj_set_style_text_color(label_1,lv_color_hex(0xFF0000),0);       //设置颜色
    
    lv_obj_t *label_2 = lv_label_create(lv_scr_act());                  //建立一个标签对象
    lv_label_set_text(label_2, "Display right:\r\nHello word");          //给他打个字
    lv_obj_align(label_2, LV_ALIGN_CENTER,80,0);                       //设置位置在居中右移80的位置,这样就是右边屏幕的中间了
    lv_obj_set_style_text_font(label_2,&lv_font_montserrat_14,0);        //在没修改的情况下只有这个字体能用,如果报错就注释掉
    lv_obj_set_style_text_color(label_2,lv_color_hex(0x0000FF),0);       //设置颜色

}
void loop(){
    lv_timer_handler();
    delay(5);
}

然后效果就有了

最后附上我这边的效果图

不过这屏是真的小。。。。

愿这篇文章能帮到你,共勉。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中提到了在Adafruit_GFX文件夹中包含Adafruit_GFX.cpp和Adafruit_GFX.h两个文件,并将该文件夹放置在/Libraries/文件夹中。这是为了使用Adafruit_GFX。引用中提到了在VScode PIO环境使用Adafruit ST7735和ST7789。这些引用信息可以帮助我们了解如何使用#include <Adafruit_GFX.h>这个头文件。 要使用#include <Adafruit_GFX.h>这个头文件,我们需要将Adafruit_GFX放置在我们的项目中。根据引用的描述,我们可以将Adafruit_GFX文件夹复制到项目的/Libraries/文件夹中。然后,在代码中使用#include <Adafruit_GFX.h>来包含该的头文件。这样,我们就可以使用Adafruit_GFX中提供的功能和类了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Adafruit-GFX-Library-master.zip](https://download.csdn.net/download/ling3ye/9729180)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ESP32-C3 VScode + PIO Arduino环境使用Adafruit_GFX 驱动两块0.96ST7735S拼接运行LVGL](https://blog.csdn.net/qq_43415898/article/details/128686659)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值