想要点亮LCD,需要了解ESP32-S3 LCD的软件驱动架构,也就是驱动软件写在什么地方,我们要更改的话到哪里改?
ESP32-S3给了很多文档,但看起来不是很清楚,笔者通过自己阅读ESP-IDF框架,结合esp-who开发的驱动,摸索总结出来了一条修改外设驱动,清晰的思路。对初次接触EP32和初次接触FreeRTOS下修改朋友一点有用。
1. ESP32-S3的驱动框架,以LCD驱动为例

1.1 ESP-IDF的驱动,都是组件,放在espressif/frameworks/esp-idf-v4.4-4/components目录下如下图:component是组件,ESP32所有的外设都可以看做是一个独立的组件,方便移植。
1.2 esp-lcd作为显示组件,其子目录就是LCD的驱动代码架构如下:

1.3 LCD的驱动结构
文件目录架构如下
我们要用的LCD驱动要添加的地方就在这个controller文件夹下:
这里对应LCD的驱动芯片,修改其.c .h来对应你的硬件方案
2. 项目构建
知道了驱动要添加的地方,接下来就要建立自己的project,来实现要的LCD点亮效果。ESP32的项目构建不同于STM32,有一套自己的方法,使用ESP-IDF的物联网开发框架。主要工具idf.py来编译、下载。工程文件的基本构成如下:关于项目构建,请阅读 构建系统 - ESP32 - — ESP-IDF 编程指南 latest 文档 (espressif.com)
- myProject/
- CMakeLists.txt
- sdkconfig
- components/ - component1/ - CMakeLists.txt
- Kconfig
- src1.c
- component2/ - CMakeLists.txt
- Kconfig
- src1.c
- include/ - component2.h
- main/ - CMakeLists.txt
- src1.c
- src2.c
- build/
2.1 建立自己的工程文件夹如下:
组件中的bus、screen从 esp-who的代码文件直接copy到这里,然后修改Cmakelists.txt如下:
2.2 在main组件中,添加main.c 代码,并修改main组件的Cmakelists.txt
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_task_wdt.h"
#include "logo_en_240x240_lcd.h"
#include "screen_driver.h"
//#include "img_array.h"
static const char TAG = "My_lcd";
static scr_driver_t g_lcd;
static scr_info_t g_lcd_info;
void app_lcd_draw_wallpaper()
{
scr_info_t lcd_info;
g_lcd.get_info(&lcd_info);
//uint16_t pixels = (uint16_t )heap_caps_malloc((logo_en_240x240_lcd_width logo_en_240x240_lcd_height) sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
// if (NULL == pixels)
// {
// ESP_LOGE(TAG, "Memory for bitmap is not enough");
// return;
// }
// memcpy(pixels, logo_en_240x240_lcd, (logo_en_240x240_lcd_width logo_en_240x240_lcd_height) sizeof(uint16_t));
//#define LV_COLOR_DEPTH 8
g_lcd.draw_bitmap(0, 0, logo_en_240x240_lcd_width, logo_en_240x240_lcd_height, (uint16_t ) logo_en_240x240_lcd);
//heap_caps_free(pixels);
}
void app_lcd_set_color(int color)
{
scr_info_t lcd_info;
g_lcd.get_info(&lcd_info);
uint16_t buffer = (uint16_t )malloc(lcd_info.width sizeof(uint16_t));
if (NULL == buffer)
{
ESP_LOGE(TAG, "Memory for bitmap is not enough");
}
else
{
for (size_t i = 0; i < lcd_info.width; i++)
{
buffer[i] = color;
}
for (int y = 0; y < lcd_info.height; y++)
{
g_lcd.draw_bitmap(0, y, lcd_info.width, 1, buffer);
}
free(buffer);
}
}
void app_main(void)
{
esp_err_t ret = ESP_OK;
//LCD SPI 设置
spi_config_t bus_conf = {
.miso_io_num = -1,
.mosi_io_num = 47,
.sclk_io_num = 21,
.max_transfer_sz = 2 240 240 + 10,
};
//创建spi bus
spi_bus_handle_t spi_bus = spi_bus_create(SPI2_HOST, &bus_conf);
//spi interface 设置,对应硬件的IO口
scr_interface_spi_config_t spi_lcd_cfg = {
.spi_bus = spi_bus,
.pin_num_cs = 44,
.pin_num_dc = 43,
.clk_freq = 40 1000000,
.swap_data = 0,
};
scr_interface_driver_t iface_drv;
scr_interface_create(SCREEN_IFACE_SPI, &spi_lcd_cfg, &iface_drv);
ret = scr_find_driver(SCREEN_CONTROLLER_ST7789, &g_lcd);
if (ESP_OK != ret)
{
ESP_LOGE(TAG, "screen find failed");
return;
}
scr_controller_config_t lcd_cfg = {
.interface_drv = iface_drv,
.pin_num_rst = -1,
.pin_num_bckl = 48,
.rst_active_level = 0,
.bckl_active_level = 0,
.offset_hor = 0,
.offset_ver = 0,
.width = 240,
.height = 240,
.rotate = 0,
};
ret = g_lcd.init(&lcd_cfg);
g_lcd.get_info(&g_lcd_info);
ESP_LOGI(TAG, "Screen name:%s | width:%d | height:%d", g_lcd_info.name, g_lcd_info.width, g_lcd_info.height);
app_lcd_set_color(0x000000);
/ Draw a red point at position (10, 20) /
g_lcd.draw_pixel(10, 20, 0x88);
vTaskDelay(pdMS_TO_TICKS(200));
app_lcd_draw_wallpaper();
vTaskDelay(pdMS_TO_TICKS(200));
}
3. 编译下载
打开ESP-IDF4.4 powershell
进入工程文件夹目录
设置硬件芯片选择:idf.py set-target esp32s3
idf.py build
烧录 idf.py flash monitor
显示没有连接串口,接上硬件板
重新运行 idf.py flash monitor
最后显示的图片效果如下:
想要更换不同的开机log 调用不同图片就ok;
感谢朋友们的关注,文档中难免有不完善的部分,还请海涵。