04_【正点原子】DNESP32S3开发板显示图片
·
开发板 【正点原子】DNESP32S3开发板

基于 ESP-IDF esp_lcd 驱动框架,驱动 ST7789 SPI 液晶屏(320*240),搭配 XL9555 I2C IO 扩展芯片控制 LCD 电源、硬件复位;支持两种显示模式:波纹动画特效 / 静态原图显示,采用双行缓冲 DMA 分片刷屏提升 SPI 传输效率。
SPI 总线初始化
spi_bus_config_t buscfg = {
.sclk_io_num = EXAMPLE_PIN_NUM_PCLK,
.mosi_io_num = EXAMPLE_PIN_NUM_DATA0,
.miso_io_num = -1, // 单向SPI,无读取,MISO不使用
.quadwp_io_num = -1,
.quadhd_io_num = -1,
// 单次SPI最大传输长度:分片行数×宽度×2字节像素 + 头部预留
.max_transfer_sz = PARALLEL_LINES * EXAMPLE_LCD_H_RES * 2 + 8
};
// 挂载SPI2总线,自动分配DMA通道
ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO));
创建 SPI-LCD IO 适配器
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_io_spi_config_t io_config = {
.dc_gpio_num = EXAMPLE_PIN_NUM_DC,
.cs_gpio_num = EXAMPLE_PIN_NUM_CS,
.pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
.spi_mode = 0, // SPI模式0 CPOL=0 CPHA=0,ST7789标准
.trans_queue_depth = 10, // SPI异步传输队列深度,缓存多笔刷屏请求
};
// 绑定SPI总线生成IO句柄
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle));
创建 ST7789 面板驱动 & 屏幕参数配置
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_RST, // 无直连复位脚,填NC
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, // 像素色彩顺序RGB
.bits_per_pixel = 16, // RGB565 16bit色深
};
// 实例化ST7789厂商驱动,生成全局panel_handle
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
// 执行ST7789寄存器初始化(发送初始化指令序列)
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
// 打开屏幕显示输出
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true)); // 反转颜色(适配屏幕底色)
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true)); // 交换XY轴(旋转90度)
ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, true, false));// X轴镜像,Y轴不镜像
图片显示函数
extern uint16_t *pixels; // 外部全局原图缓冲区(外部文件定义的全屏RGB565图像)
for (int y = 0; y < EXAMPLE_LCD_V_RES; y += PARALLEL_LINES)
{
uint16_t *dst = s_lines[calc_line]; // 目标DMA缓冲
// 遍历分片内每一行
for (int yy = 0; yy < PARALLEL_LINES; yy++)
{
int real_y = y + yy;
// 拷贝单行所有像素到DMA缓冲
for (int x = 0; x < EXAMPLE_LCD_H_RES; x++)
{
*dst++ = pixels[real_y * EXAMPLE_LCD_H_RES + x];
}
}
sending_line = calc_line;
calc_line = !calc_line;
esp_lcd_panel_draw_bitmap(panel_handle, 0, y, EXAMPLE_LCD_H_RES, y + PARALLEL_LINES, s_lines[sending_line]);
}
更多推荐
所有评论(0)