资讯动态

ESP-IDF Parallel IO 模拟 SPI / I80 接口 LCD 驱动指南:从配置到源码原理

发布时间:2026/9/16 10:11:53 来源:尧图企业网站定制
ESP-IDF Parallel IO 模拟 SPI / I80 接口 LCD 驱动指南从配置到源码原理【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf导读本文围绕 ESP-IDFesp_lcd组件中的Parallel IO并行 IOLCD 驱动器展开。该驱动并非一种总线外设而是直接为 LCD 创建一个Parallel IO 设备Panel IO通过 Parallel IOPARLIO外设模拟 SPI1 bit 数据宽度或 Intel 8080I808 bit 数据宽度接口从而驱动对应接口的 LCD 屏。读完本文你将掌握esp_lcd_new_panel_io_parl()创建 Parallel IO 设备的完整参数配置、LCD 控制器驱动的安装步骤以及从驱动源码esp_lcd_panel_io_parl.c到官方示例parlio_simulate_example_main.c的完整调用链路。一、Parallel IO LCD 驱动概述Parallel IO 本身不是总线类型的外设因此esp_lcd组件中没有 PARLIO bus driver 的概念而是由 LCD 驱动器直接创建用于 LCD 的 Parallel IO 设备Panel IO。当前驱动支持两种模拟模式SPI 模式数据总线位宽为 1 bit1 根数据线即 MOSI 单线 SPI 时序I80 模式数据总线位宽为 8 bitIntel 8080 并行时序8 根数据线。这一设计意图在源码注释中写得很直白esp_lcd_panel_io_parl.cAlthough were manipulating Parlio peripheral, it has nothing to do with the Parlio. In fact, were simulating the Intel 8080 (8>esp_err_t esp_lcd_new_panel_io_parl(const esp_lcd_panel_io_parl_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io);返回值语义与源码中的错误路径一一对应返回值含义触发场景ESP_OK创建成功—ESP_ERR_INVALID_ARG参数非法io_config/ret_io为空或data_width不是 1/8ESP_ERR_NO_MEM内存不足为设备结构体分配内存失败ESP_ERR_NOT_SUPPORTED配置无法满足如像素时钟超出 PARLIO 外设支持范围2.1 配置结构体全字段解析配置结构体esp_lcd_panel_io_parl_config_t定义在 esp_lcd_io_parl.h各字段说明如下字段类型说明clk_srcparlio_clock_source_tParallel IO 设备的时钟源。注意不同 ESP 芯片的默认时钟源可能不同建议使用PARLIO_CLK_SRC_DEFAULTclk_gpio_numgpio_num_t像素时钟引脚LCD 规格书中常称为WR或SCLKdc_gpio_numgpio_num_t数据/命令选择引脚LCD 规格书中常称为RScs_gpio_numgpio_num_t片选引脚。注意Parallel IO LCD 驱动只支持单个 LCD 设备测试代码test_parlio_lcd_panel.c验证了第二次调用esp_lcd_new_panel_io_parl会返回ESP_ERR_NOT_FOUNDdata_gpio_nums[8]gpio_num_t数据总线 GPIO 数组GPIO 数量必须等于data_widthESP_PARLIO_LCD_WIDTH_MAX为 8data_widthsize_t数据总线位宽仅支持 1SPI或 8I80pclk_hzuint32_t像素时钟频率Hz。频率越高刷新率越高但若 DMA 带宽不足或 LCD 控制芯片不支持会导致显示异常max_transfer_bytessize_t单次事务可传输的最大字节数决定内部 DMA 描述符链DMA link的长度dma_burst_sizesize_tDMA 突发传输字节数常见取 16/32/64trans_queue_depthsize_t事务队列深度。值越大可排队的事务越多、吞吐越高但内存占用也更大源码中若设为 0 会被替换为默认值 4lcd_cmd_bitsintLCD 命令位宽LCD 控制芯片能识别的命令字节数lcd_param_bitsintLCD 参数位宽dc_levels.dc_cmd_level位域命令阶段 DC 线的有效电平dc_levels.dc_data_level位域数据阶段 DC 线的有效电平flags.cs_active_high位域置 1 表示 CS 高电平有效否则 CS 低电平有效其中lcd_cmd_bits与lcd_param_bits是芯片相关参数需要提前查阅 LCD 规格书确认不同厂商、不同型号的 LCD 控制芯片命令/参数位宽并不相同。2.2 官方文档配置示例可复制官方文档给出的完整配置代码如下esp_lcd_panel_io_handle_t io_handle NULL; esp_lcd_panel_io_parl_config_t io_config { .clk_src PARLIO_CLK_SRC_DEFAULT, .dc_gpio_num EXAMPLE_PIN_NUM_DC, .clk_gpio_num EXAMPLE_PIN_NUM_PCLK, .data_gpio_nums { EXAMPLE_PIN_NUM_DATA0, // 驱动 SPI 接口 LCD 时仅设置 DATA0 // 驱动 I80 接口 LCD 时需设置 DATA0~7 }, .data_width 1, // 驱动 SPI 接口 LCD 设为 1驱动 I80 接口 LCD 设为 8 .max_transfer_bytes EXAMPLE_LCD_H_RES * 100 * sizeof(uint16_t), // 单次事务最多传输 100 行像素假设像素格式为 RGB565 .dma_burst_size EXAMPLE_DMA_BURST_SIZE, .cs_gpio_num EXAMPLE_PIN_NUM_CS, .pclk_hz EXAMPLE_LCD_PIXEL_CLOCK_HZ, .trans_queue_depth 10, .dc_levels { .dc_cmd_level 0, .dc_data_level 1, }, .lcd_cmd_bits EXAMPLE_LCD_CMD_BITS, .lcd_param_bits EXAMPLE_LCD_PARAM_BITS, }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_parl(io_config, io_handle));2.3 源码中的参数映射与硬件初始化细节从 esp_lcd_panel_io_parl.c 的esp_lcd_new_panel_io_parl()实现可以看到该 API 内部做了以下几件关键工作位宽校验#if SOC_PARLIO_SUPPORT_I80_LCD分支下允许 1 或 8否则只允许 1直接返回ESP_ERR_INVALID_ARG。创建 PARLIO TX 单元调用parlio_new_tx_unit()将上层 LCD 配置映射为 PARLIO 外设配置clk_in_gpio_num -1使用内部时钟源valid_gpio_num对应 CS 引脚output_clk_freq_hz对应pclk_hzshift_edge PARLIO_SHIFT_EDGE_NEG负沿移位输出bit_pack_order PARLIO_BIT_PACK_ORDER_MSB高位先出flags.invert_valid_out !io_config-flags.cs_active_high将 CS 有效电平翻译为 valid 输出极性。注册传输完成回调parlio_tx_unit_register_event_callbacks()绑定默认 ISR 回调lcd_default_isr_callback。DC 信号由软件控制dc_gpio_num被配置为普通 GPIOgpio_func_selgpio_output_enable在发送命令、参数、颜色数据前由软件切换 DC 电平见panel_io_parl_tx_param与panel_io_parl_tx_color。填充 Panel IO 函数表del/tx_param/tx_color/register_event_callbacks四个标准接口。最后使能 TX 单元parlio_tx_unit_enable(tx_unit)并返回esp_lcd_panel_io_t基类句柄。值得注意的一个字节序细节LCD 通常是大端传输例如发送命令0x1234时0x12应先出现在数据总线上而 PARLIO 外设会先发送低位字节因此parlio_lcd_prepare_cmd_buffer()中通过lcd_com_reverse_buffer_bytes()将命令/参数缓冲区的字节顺序反转后再提交传输。此外驱动还提供esp_lcd_parlio_alloc_draw_buffer()esp_lcd_io_parl.h来分配绘图缓冲区它不同于普通的heap_caps_*分配会自动处理 DMA 突发对齐、cache line 对齐等约束当请求MALLOC_CAP_SPIRAM时从外部内存分配否则从内部 DMA 内存分配见 esp_lcd_panel_io_parl.c。三、第二步安装 LCD 控制器驱动创建好 Parallel IO 设备后下一步安装LCD 控制器驱动。控制器驱动负责向 LCD 控制芯片发送命令和参数创建时需要传入上一步得到的 Parallel IO 设备句柄io_handle以及面板特定配置。3.1 配置结构体全字段解析面板设备配置结构体esp_lcd_panel_dev_config_t定义在 esp_lcd_panel_dev.h字段类型说明reset_gpio_numgpio_num_tLCD 硬件复位引脚。若 LCD 没有硬件复位脚设为-1rgb_ele_orderlcd_rgb_element_order_t每个颜色数据中 RGB 元素的顺序LCD_RGB_ELEMENT_ORDER_RGB或LCD_RGB_ELEMENT_ORDER_BGRbits_per_pixeluint32_t像素颜色数据位宽bpp。LCD 驱动据此计算发送给控制芯片的字节数常见 16RGB565data_endianlcd_rgb_data_endian_t发送到屏幕的颜色数据字节序。单字节内的颜色数据如 RGB232无需指定不支持指定字节序的驱动会忽略该字段vendor_configvoid *厂商特定配置可选不用时置NULLflags.reset_active_high位域置 1 表示复位为高电平有效3.2 官方文档配置示例可复制esp_lcd_panel_handle_t panel_handle NULL; esp_lcd_panel_dev_config_t panel_config { .reset_gpio_num EXAMPLE_PIN_NUM_RST, .rgb_ele_order LCD_RGB_ELEMENT_ORDER_BGR, .bits_per_pixel 16, }; // 为 ST7789 创建 LCD panel 句柄传入上一步得到的 Parallel IO 设备句柄 ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, panel_config, panel_handle));esp_lcd_new_panel_st7789()是esp_lcd组件内置的 ST7789 控制器驱动创建函数其余常见控制器如 SSD1306 等也有对应的esp_lcd_new_panel_xxx()系列 API。创建完成后即可通过esp_lcd_panel_reset()、esp_lcd_panel_init()、esp_lcd_panel_draw_bitmap()等标准操作接口驱动屏幕。四、完整实战官方 parlio_simulate 示例官方示例 examples/peripherals/lcd/parlio_simulate 将上述两步串成了可运行的完整流程适合作为移植模板void example_init_parlio_panel(esp_lcd_panel_io_handle_t *io_handle) { ESP_LOGI(TAG, Initialize Parlio device); esp_lcd_panel_io_parl_config_t io_config { .clk_src PARLIO_CLK_SRC_DEFAULT, .dc_gpio_num EXAMPLE_PIN_NUM_DC, .clk_gpio_num EXAMPLE_PIN_NUM_PCLK, .data_gpio_nums { EXAMPLE_PIN_NUM_DATA0, #if CONFIG_EXAMPLE_LCD_PARLIO_SIMULATE_I80 EXAMPLE_PIN_NUM_DATA1, ... EXAMPLE_PIN_NUM_DATA7, // I80 模式补充 DATA1~7 #endif }, .data_width CONFIG_EXAMPLE_LCD_PARLIO_DATA_WIDTH, // 1 或 8 .max_transfer_bytes EXAMPLE_LCD_H_RES * EXAMPLE_LVGL_DRAW_BUF_LINES * sizeof(uint16_t), .dma_burst_size EXAMPLE_DMA_BURST_SIZE, // 32 .cs_gpio_num EXAMPLE_PIN_NUM_CS, .pclk_hz EXAMPLE_LCD_PIXEL_CLOCK_HZ, .trans_queue_depth 10, .dc_levels { .dc_cmd_level 0, .dc_data_level 1 }, .lcd_cmd_bits EXAMPLE_LCD_CMD_BITS, // 8 .lcd_param_bits EXAMPLE_LCD_PARAM_BITS, // 8 }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_parl(io_config, io_handle)); } void example_init_lcd_panel(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_handle_t *panel) { esp_lcd_panel_dev_config_t panel_config { .reset_gpio_num EXAMPLE_PIN_NUM_RST, .rgb_ele_order LCD_RGB_ELEMENT_ORDER_RGB, .bits_per_pixel 16, }; ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, panel_config, panel_handle)); esp_lcd_panel_reset(panel_handle); esp_lcd_panel_init(panel_handle); esp_lcd_panel_invert_color(panel_handle, true); // 按 LCD 模组规格设置反色 esp_lcd_panel_set_gap(panel_handle, 0, 20); // gap 与驱动 IC 及模组相关 *panel panel_handle; }该示例的 KconfigKconfig.projbuild提供以下可配置项可作为实际项目的参数参考EXAMPLE_LCD_PARLIO_SIMULATE_INTERFACE选择模拟接口。默认在支持 I80 的芯片上选择 I80否则选择 SPIEXAMPLE_LCD_PIXEL_CLOCK_HZ像素时钟频率默认 10 MHzEXAMPLE_LCD_PARLIO_DATA_WIDTHI80 模式自动设为 8SPI 模式为 1EXAMPLE_LCD_PARLIO_COLOR_IN_PSRAM是否从 PSRAM 分配 LVGL 绘图缓冲依赖SOC_PSRAM_DMA_CAPABLE引脚配置PCLK默认 5、CS默认 3、DC默认 4、RST默认 2、背光默认 1、DATA0默认 6I80 模式下 DATA1~DATA7 默认 25~31。示例还演示了 LVGL 移植要点example_notify_lvgl_flush_ready()作为on_color_trans_done事件回调通知 LVGL 刷新完成example_lvgl_flush_cb()中因 LCD 大端特性调用lv_draw_sw_rgb565_swap()交换 RGB565 字节序后再调用esp_lcd_panel_draw_bitmap()将缓冲区内容绘制到屏幕指定区域。五、API 参考速览Parallel IO 设备相关的完整 API 声明见 esp_lcd_io_parl.h核心接口归纳如下esp_lcd_new_panel_io_parl()创建 Parallel IO Panel IO 设备esp_lcd_parlio_alloc_draw_buffer()分配满足 DMA 突发/cache line 对齐约束的绘图缓冲区支持从 PSRAM 或内部内存分配设备句柄通过标准 Panel IO 接口esp_lcd_panel_io_tx_param、esp_lcd_panel_io_tx_color、esp_lcd_panel_io_register_event_callbacks、esp_lcd_panel_io_del使用上层控制器驱动无需感知底层是 PARLIO 模拟还是真实 SPI/I80 总线。六、总结与注意事项使用 Parallel IO 模拟 SPI/I80 LCD 时需要重点把握以下几点位宽选择受限data_width仅支持 1SPI或 8I80且 I80 模式依赖芯片的SOC_PARLIO_SUPPORT_I80_LCD能力选型前需确认目标芯片支持情况。单设备约束Parallel IO LCD 驱动只支持单个 LCD 设备重复创建会失败。时钟与带宽平衡pclk_hz决定刷新率上限但过高的像素时钟在 DMA 带宽不足或 LCD 控制器不支持时会引发显示异常需结合实际屏幕与系统资源调整。命令/参数位宽按芯片规格设置lcd_cmd_bits与lcd_param_bits必须先查 LCD 规格书否则命令与参数无法被正确解析。字节序处理LCD 大端特性与 PARLIO 外设小端输出之间的差异由驱动内部自动处理命令/参数反转 示例中 RGB565 交换应用层只需按 Panel IO 标准接口发送数据即可。相关文件索引驱动实现components/esp_lcd/parl/esp_lcd_panel_io_parl.c驱动头文件components/esp_lcd/include/esp_lcd_io_parl.h面板设备配置components/esp_lcd/include/esp_lcd_panel_dev.h单元测试components/esp_lcd/test_apps/parlio_lcd/main/test_parlio_lcd_panel.c官方示例examples/peripherals/lcd/parlio_simulate/main/parlio_simulate_example_main.c【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价