ESP32-P4 MIPI摄像头5分钟跑通实时显示,4处关键代码上屏
【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf
ESP-IDF 把 ESP32-P4 的 MIPI 摄像头链路整合进了一个示例:MIPI-CSI 采集、片上 ISP 做 RAW 转 RGB、DSI 直接写屏。硬件备好 P4 开发板、OV5647 与 DSI 屏的话,克隆仓库后 5 分钟就能见到实时画面。
📷 从传感器到屏幕:ESP32-P4 MIPI 摄像头的一条数据通路
P4 的 MIPI 摄像头路线和老式 DVP 并行摄像头不同:传感器走 2 lane 串行差分信号,配合 MIPI-CSI(芯片间高速图像传输协议),比 DVP 十几根并行线在高分辨率下更稳、走线也少出错;芯片内还自带硬件 ISP,能把传感器输出的 RAW 数据直接转成屏认识的 RGB565。仓库里的mipi_isp_dsi示例把 I2C、CSI、DSI 三个模块串成一条通路,OV5647、SC2336 等传感器都能自动识别。
git clone https://gitcode.com/GitHub_Trending/es/esp-idf cd esp-idf/examples/peripherals/camera/mipi_isp_dsi . ../../export.sh idf.py set-target esp32p4 idf.py build flash monitor跑完后屏幕会直接显示摄像头画面,串口里会打出传感器 PID 和选中的格式。先别急着抠原理,这条通路的每一跳拆开看其实不复杂。
🔧 跟着一帧图像走完 MIPI-CSI、ISP、DSI 的 4 跳
按数据流向把通路拆开,每一跳只回答一个问题。
I2C 上如何认出传感器
传感器寄存器走 SCCB(本质就是 I2C),example_sensor_init会在总线上探测已接入的传感器并比对 PID,像门口按门铃,谁响就开谁的门:
example_sensor_config_t cam_sensor_config = { .i2c_port_num = I2C_NUM_0, .i2c_sda_io_num = EXAMPLE_MIPI_CSI_CAM_SCCB_SDA_IO, .i2c_scl_io_num = EXAMPLE_MIPI_CSI_CAM_SCCB_SCL_IO, .port = ESP_CAM_SENSOR_MIPI_CSI, .format_name = EXAMPLE_CAM_FORMAT, };format_name 是和传感器约定分辨率与帧率的字符串,必须写成驱动支持的完整格式名,自动检测才能对得上。OV5647 自带 ISP,SC2336 没有,后者全靠片上 ISP 兜底。
CSI 收 RAW8 时参数怎么配
esp_cam_ctlr_csi_config_t csi_config = { .h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, .v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES, .lane_bit_rate_mbps = EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS, .input_data_color_type = CAM_CTLR_COLOR_RAW8, .data_lane_num = 2, };RAW8 是传感器输出的未压缩单通道原始数据,CSI 控制器只管收、不改像素内容,输入格式必须如实声明。
⚠️
h_res/v_res必须和屏一致:相机横分辨率跟屏对不上时,画面会错位、撕裂,这是最常见的翻车点。
ISP 把 RAW 变成 RGB565
esp_isp_processor_cfg_t isp_config = { .clk_hz = 80 * 1000 * 1000, .input_data_source = ISP_INPUT_DATA_SOURCE_CSI, .input_data_color_type = ISP_COLOR_RAW8, .output_data_color_type = ISP_COLOR_RGB565, .h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, .v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES, };ISP 输入源直接挂 CSI,RAW 转 RGB 全程硬件速度完成,CPU 一个像素都不用搬。
DSI 输出前为什么不能读旧数据
DSI 屏从一块帧缓冲区取画面,CPU 改过内容后必须把缓存刷回主存,面板才看得到:
memset(frame_buffer, 0xFF, frame_buffer_size); esp_cache_msync((void *)frame_buffer, frame_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);这行 msync 最容易漏,漏掉它屏幕会一直停在白屏或上一帧。
🚦 编译烧录一次验证 MIPI-CSI 上屏
端到端 8 步:
| 步骤 | 操作 |
|---|---|
| 1 | git clone https://gitcode.com/GitHub_Trending/es/esp-idf |
| 2 | 进入 mipi_isp_dsi 示例目录,. ../../export.sh |
| 3 | idf.py set-target esp32p4 |
| 4 | idf.py menuconfig:勾选对应传感器,Example DSI Configuration 里选屏型号与分辨率 |
| 5 | idf.py build flash monitor |
| 6 | 串口等待Detected Camera sensor PID=0x5647 |
| 7 | 确认屏上出现实时画面 |
| 8 | 异常时按Ctrl+]退出 monitor,看串口日志定位 |
看到这样的输出就算跑对了:
Executing action: monitor Running idf_monitor... I (1085) main_task: Calling app_main() I (1095) ili9881c: ID1: 0x98, ID2: 0x81, ID3: 0x5c I (1295) ov5647: Detected Camera sensor PID=0x5647 with index 0 I (1355) sensor_init: Format in use:MIPI_2lane_24Minput_RAW8_800x640_50fpsili9881c 两行是屏自检通过,ov5647 行说明传感器被识别,最后一行是实际生效的采集格式。
OV5647 接 ILI9881C 的 DSI 屏实时输出,ESP32-P4 MIPI-CSI 摄像头显示样例的实测画面
🧭 画面跑起来之后:ISP 多管线与边缘推理的 3 个方向
- 画面偏色、不够锐利时,给片上 ISP 开 AWB、自动对焦等管线,
examples/peripherals/isp/multi_pipelines/有多管线调法参考:
开启片上 ISP 多管线处理后的输出,白平衡与清晰度明显改善
- 同一套
components/esp_driver_cam/里还有 DVP 控制器,换 OV2640 这类并行传感器时代码风格基本不变,改的是采集侧配置。 - RGB565 帧和轻量 AI 推理的输入格式一致,直接喂给推理组件做识别,无需再做一次格式转换。
继续深挖:https://gitcode.com/GitHub_Trending/es/esp-idf
【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考