ESP32 IDF开发——RGB LCD显示屏(ST7701S)
目录
1 硬件描述
我这里用的LCD是RGB接口的,驱动IC为ST7701S,用ESP32S3驱动,RGB565 16根数据线,接线如下:
ESP32S3 | LCD | SPI数据线 |
---|---|---|
IO48 | SDA | SPI数据线 |
IO16 | SCK | SPI时钟线 |
IO15 | CS | SPI片选线 |
IO14 | PCLK | RGB时钟线 |
IO13 | DE | RGB数据使能 |
IO12 | VSYNC | 垂直同步 |
IO11 | HSYNC | 水平同步 |
空 | DB0 | 数据线0 |
IO10 | DB1 | 数据线1 B1 |
IO9 | DB2 | 数据线2 B2 |
IO8 | DB3 | 数据线3 B3 |
IO7 | DB4 | 数据线4 B4 |
IO6 | DB5 | 数据线5 B5 |
IO5 | DB6 | 数据线6 G0 |
IO4 | DB7 | 数据线7 G1 |
IO3 | DB8 | 数据线8 G2 |
IO2 | DB9 | 数据线9 G3 |
IO1 | DB10 | 数据线10 G4 |
IO0 | DB11 | 数据线11 G5 |
空 | DB12 | 数据线12 |
IO42 | DB13 | 数据线13 R1 |
IO41 | DB14 | 数据线14 R2 |
IO40 | DB15 | 数据线15 R3 |
IO39 | DB16 | 数据线16 R4 |
IO38 | DB17 | 数据线17 R5 |
2 软件编程
开发环境基于VScode + ESP-IDF。关于RGB屏幕显示原理,这里不细说,只讲编程,感兴趣的同学可以自行查阅。
注:关于怎么在Vscode里面搭建ESP-IDF的开环环境,这里不具体说了,网上教程很多,不懂的同学请先自行搭建好环境。
2.1 新建工程
打开ESP-IDF,点击Show example
。
选择rgb_panel
例程作为我们的工程的基础模版。
保存至本地,会得到一个工程模板,如下图:
在最底下的状态栏,配置目标芯片,要选择esp32s3
。
注:esp32s3具备rgb接口,其他像esp32和esp32s2是没有的。
打开配置列表,配置时钟、FLASH和PSRAM等参数。
我的配置如下(仅供参考):
初步编译一下。
注:因为这个模板默认把lvgl库加进来了,因此在编译的时候会自动下载lvgl组件并参与编译。如果不需要使用lvgl的话可以在idf_component.yml
文件里面把lvgl/lvgl: "~8.3.0"
删掉,这样就不会把lvgl加入进来,同时,还要把main里面所有跟lvgl相关的代码删掉,才能编译通过。
编译如果通过后,那工程的建立就没问题了。
2.2 编写ST7701S驱动程序
在工程main文件夹目录下新建st7701s.c
和st7701s.h
文件,并且在CMakeLists.txt
文件加入"st7701s.c",如下:
添加st7701s.c之前:
idf_component_register(SRCS "rgb_lcd_example_main.c" "lvgl_demo_ui.c"
INCLUDE_DIRS ".")
添加st7701s.c之后:
idf_component_register(SRCS "rgb_lcd_example_main.c" "lvgl_demo_ui.c" "st7701s.c"
INCLUDE_DIRS ".")
文件目录如下:
然后编写ST7701S驱动程序,示例代码如下:
st7701s.c:
#include "st7701s.h"
#define SPI_WriteComm(cmd) st7701s_write_cmd(st7701s_handle, cmd)
#define SPI_WriteData(data) st7701s_write_data(st7701s_handle, data)
#define Delay(ms) vTaskDelay(ms / portTICK_PERIOD_MS)
void ioexpander_init(){
};
void ioexpander_write_cmd(){
};
void ioexpander_write_data(){
};
/**
* @brief 新建st7701s对象
* @param sda sda引脚
* @param scl scl引脚
* @param cs cs引脚
* @param channel_select SPI, I2C通道选择
* @param method_select 可以选择SPI_METHOD,IOEXPANDER_METHOD
* @note channel_select可选SPI控制器, SPI3_HOST OR SPI4_HOST in ESP32S3
* @note channel_select可选I2C控制器
*/
vernon_st7701s_handle st7701s_new_object(int sda, int scl, int cs, char channel_select, char method_select)
{
// if you use `malloc()`, please set 0 in the area to be assigned.
vernon_st7701s_handle vernon_st7701s_handle = heap_caps_calloc(1, sizeof(vernon_st7701s), MALLOC_CAP_DEFAULT);
vernon_st7701s_handle->method_select = method_select;
if(method_select)
{
vernon_st7701s_handle->spi_io_config_t.miso_io_num = -1;
vernon_st7701s_handle->spi_io_config_t.mosi_io_num = sda;
vernon_st7701s_handle->spi_io_config_t.sclk_io_num = scl;
vernon_st7701s_handle->spi_io_config_t.quadwp_io_num = -1;
vernon_st7701s_handle->spi_io_config_t.quadhd_io_num = -1;
// 默认值,启用DMA应设置为0
vernon_st7701s_handle->spi_io_config_t.max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE;
// 不使用DMA最后赋值0
ESP_ERROR_CHECK(spi_bus_initialize(channel_select, &(vernon_st7701s_handle->spi_io_config_t), 0));
vernon_st7701s_handle->st7701s_protocol_config_t.command_bits = 1;
vernon_st7701s_handle->st7701s_protocol_config_t.address_bits = 8;
vernon_st7701s_handle->st7701s_protocol_config_t.clock_speed_hz = 40000000;
/**
* < 时钟极性以及时钟相位设置(CPOL, CPHA):
- 0: (0, 0)
- 1: (0, 1)
- 2: (1, 0)
- 3: (1, 1)
**/
vernon_st7701s_handle->st7701s_protocol_config_t.mode = 0;
vernon_st7701s_handle->st7701s_protocol_config_t.spics_io_num = cs;
vernon_st7701s_handle->st7701s_protocol_config_t.queue_size = 1;
ESP_ERROR_CHECK(spi_bus_add_device(channel_select, &(vernon_st7701s_handle->st7701s_protocol_config_t),
&(vernon_st7701s_handle->spi_device)));
return vernon_st7701s_handle;
}
else
{
ioexpander_init();
}
return NULL;
}
/**
* @brief 屏幕初始化
* @param st7701s_handle 类实例指针
* @param type 选择初始化类型 [1~x]
* @note 以下类型来自不同地方,对应命令功能未知
*/
void st7701s_screen_init(vernon_st7701s_handle st7701s_handle, unsigned char type)
{
if (type == 1)
{
//从商家提供的资料复制
SPI_WriteComm(0x11); //sleep out í?3??ˉ???£ê?
Delay(10);
//--------------------------Bank0 Setting-----------------------------------//
//----------------------Display Control setting-----------------------------//
//--------------------------Bank1 Setting-----------------------------------//
SPI_WriteComm(0xFF);
SPI_WriteData(0x77);
SPI_WriteData(0x01);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x10);
SPI_WriteComm(0xC0);
SPI_WriteData(0x3B);
SPI_WriteData(0x00);
SPI_WriteComm(0xC1);
SPI_WriteData(0x0D);
SPI_WriteData(0x02);
SPI_WriteComm(0xC2);
SPI_WriteData(0x31);
SPI_WriteData(0x05);
//--------------------------Gamma Cluster Setting--------------------------//
SPI_WriteComm(0xB0);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x18);
SPI_WriteData(0x0E);
SPI_WriteData(0x11);
SPI_WriteData(0x06);
SPI_WriteData(0x07);
SPI_WriteData(0x08);
SPI_WriteData(0x07);
SPI_WriteData(0x22);
SPI_WriteData(0x04);
SPI_WriteData(0x12);
SPI_WriteData(0x0F);
SPI_WriteData(0xAA);
SPI_WriteData(0x31);
SPI_WriteData(0x18);
SPI_WriteComm(0xB1);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x19);
SPI_WriteData(0x0E);
SPI_WriteData(0x12);
SPI_WriteData(0x07);
SPI_WriteData(0x08);
SPI_WriteData(0x08);
SPI_WriteData(0x08);
SPI_WriteData(0x22);
SPI_WriteData(0x04);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0xA9);
SPI_WriteData(0x32);
SPI_WriteData(0x18);
//-------------------------Bank1 Setting---------------------------------//
SPI_WriteComm(0xFF);
SPI_WriteData(0x77);
SPI_WriteData(0x01);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteComm(0xb0);
SPI_WriteData(0x60);
//--------------------------Vcom Setting--------------------------------//
SPI_WriteComm(0xb1);
SPI_WriteData(0x32);
//-----------------------End Vcom Setting------------------------------//
SPI_WriteComm(0xb2);
SPI_WriteData(0x07);
SPI_WriteComm(0xb3);
SPI_WriteData(0x80);
SPI_WriteComm(0xb5);
SPI_WriteData(0x49);
SPI_WriteComm(0xb7);
SPI_WriteData(0x85);
SPI_WriteComm(0xb8);
SPI_WriteData(0x21);
SPI_WriteComm(0xC1);
SPI_WriteData(0x78);
SPI_WriteComm(0xC2);
SPI_WriteData(0x78);
// SPI_WriteComm(0xD0);
// SPI_WriteData(0x88);
//-----------End Power Control Registers Initial ------------------//
// DelayNms(100);
//----------------GIP Setting--------------------------------------//
SPI_WriteComm(0xE0);
SPI_WriteData(0x00);
SPI_WriteData(0x1B);
SPI_WriteData(0x02);
SPI_WriteComm(0xE1);
SPI_WriteData(0x08);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x07);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteComm(0xE2);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteData(0xED);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0xEC);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteComm(0xE3);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteComm(0xE4);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteComm(0xE5);
SPI_WriteData(0x0A);
SPI_WriteData(0xE9);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x0C);
SPI_WriteData(0xEB);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x0E);
SPI_WriteData(0xED);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x10);
SPI_WriteData(0xEF);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteComm(0xE6);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteComm(0xE7);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteComm(0xE8);
SPI_WriteData(0x09);
SPI_WriteData(0xE8);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x0B);
SPI_WriteData(0xEA);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x0D);
SPI_WriteData(0xEC);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x0F);
SPI_WriteData(0xEE);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteComm(0xEB);
SPI_WriteData(0x02);
SPI_WriteData(0x00);
SPI_WriteData(0xE4);
SPI_WriteData(0xE4);
SPI_WriteData(0x88);
SPI_WriteData(0x00);
SPI_WriteData(0x40);
SPI_WriteComm(0xEC);
SPI_WriteData(0x3c);
SPI_WriteData(0x00);
SPI_WriteComm(0xED); //ok
SPI_WriteData(0xAB);
SPI_WriteData(0x89);
SPI_WriteData(0x76);
SPI_WriteData(0x54);
SPI_WriteData(0x02);
SPI_WriteData(0xFF);
SPI_WriteData(0xFF);
SPI_WriteData(0xFF);
SPI_WriteData(0xFF);
SPI_WriteData(0xFF);
SPI_WriteData(0xFF);
SPI_WriteData(0x20);
SPI_WriteData(0x45);
SPI_WriteData(0x67);
SPI_WriteData(0x98);
SPI_WriteData(0xBA);
SPI_WriteComm(0x35); SPI_WriteData(0x00); // Sleep-Out
SPI_WriteComm(0x36); SPI_WriteData(0x00);//BGR
// SPI_WriteComm(0x36); SPI_WriteData(0x08); //RGB
// SPI_WriteComm(0x3A); SPI_WriteData(0x77); //24bit
// SPI_WriteComm(0x20);//display inversion off
SPI_WriteComm(0x3A); SPI_WriteData(0x55);//16bit
// SPI_WriteComm(0x3A); SPI_WriteData(0x66);//18bit
// SPI_WriteComm(0x22);//All pixel off
// SPI_WriteCmd(0x21); //Normal Black
// SPI_WriteComm(0x11);//sleep out í?3??ˉ???£ê?
//--------------------------Bank3 Setting--------------------------------//
SPI_WriteComm(0xFF);
SPI_WriteData(0x77);
SPI_WriteData(0x01);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x13);
SPI_WriteComm(0xE5);
SPI_WriteData(0xE4);
Delay(10);
SPI_WriteComm(0x29);
}
else if(type == 2)
{
//从Arduino GFX库中移植
SPI_WriteComm(0x11); //reset command
SPI_WriteComm(0xFF);
SPI_WriteData(0x77);
SPI_WriteData(0x01);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x10);
SPI_WriteComm(0xC0);
SPI_WriteData(0x3B);
SPI_WriteData(0x00);
SPI_WriteComm(0xC1);
SPI_WriteData(0x0D);
SPI_WriteData(0x02);
SPI_WriteComm(0xC2);
SPI_WriteData(0x31);
SPI_WriteData(0x05);
SPI_WriteComm(0xCD);
SPI_WriteData(0x08);
SPI_WriteComm(0xB0);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x18);
SPI_WriteData(0x0E);
SPI_WriteData(0x11);
SPI_WriteData(0x06);
SPI_WriteData(0x07);
SPI_WriteData(0x08);
SPI_WriteData(0x07);
SPI_WriteData(0x22);
SPI_WriteData(0x04);
SPI_WriteData(0x12);
SPI_WriteData(0x0F);
SPI_WriteData(0xAA);
SPI_WriteData(0x31);
SPI_WriteData(0x18);
SPI_WriteComm(0xB1);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x19);
SPI_WriteData(0x0E);
SPI_WriteData(0x12);
SPI_WriteData(0x07);
SPI_WriteData(0x08);
SPI_WriteData(0x08);
SPI_WriteData(0x08);
SPI_WriteData(0x22);
SPI_WriteData(0x04);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0xA9);
SPI_WriteData(0x32);
SPI_WriteData(0x18);
SPI_WriteComm(0xFF);
SPI_WriteData(0x77);
SPI_WriteData(0x01);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteComm(0xB0);
SPI_WriteData(0x60);
SPI_WriteComm(0xB1);
SPI_WriteData(0x32);
SPI_WriteComm(0xB2);
SPI_WriteData(0x07);
SPI_WriteComm(0xB3);
SPI_WriteData(0x80);
SPI_WriteComm(0xB5);
SPI_WriteData(0x49);
SPI_WriteComm(0xB7);
SPI_WriteData(0x85);
SPI_WriteComm(0xB8);
SPI_WriteData(0x21);
SPI_WriteComm(0xC1);
SPI_WriteData(0x78);
SPI_WriteComm(0xC2);
SPI_WriteData(0x78);
SPI_WriteComm(0xE0);
SPI_WriteData(0x00);
SPI_WriteData(0x1B);
SPI_WriteData(0x02);
SPI_WriteComm(0xE1);
SPI_WriteData(0x08);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x07);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteComm(0xE2);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteData(0xED);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0xEC);
SPI_WriteData(0xA0);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteComm(0xE3);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteComm(0xE4);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteComm(0xE5);
SPI_WriteData(0x0A);
SPI_WriteData(0xE9);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x0C);
SPI_WriteData(0xEB);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x0E);
SPI_WriteData(0xED);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteData(0x10);
SPI_WriteData(0xEF);
SPI_WriteData(0xD8);
SPI_WriteData(0xA0);
SPI_WriteComm(0xE6);
SPI_WriteData(0x00);
SPI_WriteData(0x00);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteComm(0xE7);
SPI_WriteData(0x44);
SPI_WriteData(0x44);
SPI_WriteComm