news 2026/9/15 22:24:39

ESP-IDF 相机控制器驱动(esp_driver_cam)开发指南:MIPI CSI / ISP DVP / LCD_CAM DVP 统一接口实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ESP-IDF 相机控制器驱动(esp_driver_cam)开发指南:MIPI CSI / ISP DVP / LCD_CAM DVP 统一接口实战

ESP-IDF 相机控制器驱动(esp_driver_cam)开发指南:MIPI CSI / ISP DVP / LCD_CAM DVP 统一接口实战

【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf

本指南以 ESP-IDF 官方文档 Camera Controller Driver 为主体,系统讲解esp_driver_cam组件中相机控制器驱动的完整使用方法:如何在 MIPI CSI、ISP DVP 与 LCD_CAM DVP 三种硬件通路之间做资源分配、驱动使能、启停、收帧与事件回调,并给出缓存关闭(Cache-Safe / IRAM-Safe)场景下的配置建议。读完本文,你将能够基于esp_cam_ctlr_*系列 API 快速搭建一条"相机传感器 → 控制器 → 应用缓冲区"的完整数据通路,并理解其底层接口抽象与 SOC 能力约束。

概述:三种硬件通路与一个统一驱动接口

ESP32 系列芯片为连接外部相机传感器设计了三种硬件通路,在 components/esp_driver_cam 组件中分别由三个工厂函数承载:

  • MIPI CSISOC_MIPI_CSI_SUPPORTED):MIPI Camera Serial Interface,面向 MIPI CSI 协议相机,对应esp_cam_new_csi_ctlr
  • ISP DVPSOC_ISP_DVP_SUPPORTED):经 ISP 模块接入的 Digital Video Port,对应esp_cam_new_isp_dvp_ctlr
  • LCD_CAM DVPSOC_LCDCAM_CAM_SUPPORTED):经 LCD_CAM 模块实现的 DVP 端口,对应esp_cam_new_lcd_cam_ctlr

这些能力宏定义在各芯片的soc_caps.h中,从仓库源码可以确认当前的支持矩阵:esp32p4 同时使能了SOC_LCDCAM_CAM_SUPPORTEDSOC_MIPI_CSI_SUPPORTEDSOC_ISP_DVP_SUPPORTED;esp32s3 与 esp32s31 使能了SOC_LCDCAM_CAM_SUPPORTED

无论底层走哪条通路,驱动最终都返回统一的esp_cam_ctlr_handle_t句柄。这一统一抽象定义在 esp_cam_ctlr_interface.h 中:struct esp_cam_ctlr_t是一张纯函数指针表,包含enablestartstopdisablereceivedelregister_event_callbacksget_internal_bufferget_buffer_lenalloc_bufferformat_conversion等操作。公共 API 层 esp_cam_ctlr.c 只是对这些函数指针做参数校验(如空指针检查、能力未实现检查)后转发,因此上层业务代码可以完全与具体硬件通路解耦。

资源分配:创建相机控制器实例

三种工厂函数

创建控制器实例有三种方式,按 SOC 能力选择其一:

  • esp_cam_new_csi_ctlr(MIPI CSI,配置结构体esp_cam_ctlr_csi_config_t
  • esp_cam_new_isp_dvp_ctlr(ISP DVP,配置结构体esp_cam_ctlr_isp_dvp_cfg_t,需先创建 ISP 处理器句柄)
  • esp_cam_new_lcd_cam_ctlr(LCD_CAM DVP,配置结构体esp_cam_ctlr_dvp_config_t

创建成功后返回控制器句柄;失败时返回错误码。从 esp_cam_ctlr_csi.h 的注释可以看到典型返回值:ESP_OKESP_ERR_INVALID_ARGESP_ERR_NO_MEMESP_ERR_NOT_SUPPORTED,以及ESP_ERR_NOT_FOUND(表示该通路控制器已被注册)。

方式一:MIPI CSI 控制器

以下示例创建一个 2-lane MIPI CSI 控制器,输入 RAW8、输出 RGB565:

#include "esp_cam_ctlr.h" #include "esp_cam_ctlr_types.h" #include "esp_cam_ctlr_csi.h" void app_main(void) { esp_cam_ctlr_csi_config_t csi_config = { .ctlr_id = 0, .h_res = MIPI_CSI_DISP_HSIZE, .v_res = MIPI_CSI_DISP_VSIZE_640P, .lane_bit_rate_mbps = MIPI_CSI_LANE_BITRATE_MBPS, .input_data_color_type = CAM_CTLR_COLOR_RAW8, .output_data_color_type = CAM_CTLR_COLOR_RGB565, .data_lane_num = 2, .byte_swap_en = false, .queue_items = 1, }; esp_cam_ctlr_handle_t handle = NULL; ESP_ERROR_CHECK(esp_cam_new_csi_ctlr(&csi_config, &handle)); }

esp_cam_ctlr_csi_config_t的完整字段见 esp_cam_ctlr_csi.h,要点如下:

字段含义备注
ctlr_idCSI 控制器 ID通常取 0
clk_srcCSI PHY 时钟源mipi_csi_phy_clock_source_t类型
h_res/v_res输入水平 / 垂直分辨率单位分别为像素/行、行/帧
data_lane_num数据 lane 数如 1、2、4
lane_bit_rate_mbps单 lane 比特率单位 Mbps
input_data_color_type/output_data_color_type输入 / 输出颜色格式见下方cam_ctlr_color_t
data_type自定义数据类型默认置 0 即可支持 embedded data 与标准数据类型
queue_items队列项数内部缓冲队列深度
input_8bit_swap_en输入 8bit 位交换使能后[31:24][23:16][15:8][7:0][7:0][15:8][23:16][31:24]
input_16bit_swap_en输入 16bit 位交换使能后[31:16][15:0][15:0][31:16]
byte_swap_en输出字节交换调节输出字节序
bk_buffer_dis禁用备用缓冲区置 1 时驱动不再分配内部 backup buffer

MIPI CSI 供电要求:CSI 外设在芯片内需要稳定的 2.5 V 电源,使用前请对照原理图确认电源引脚已接 2.5 V。在支持内部可调 LDO(SOC_GP_LDO_SUPPORTED)的芯片上,可以将 LDO 通道输出引脚接到 CSI 供电引脚,在初始化 CSI 驱动前调用 ldo_regulator 的 API 将 LDO 配置为输出 2.5 V。

方式二:ISP DVP 控制器

使用 ISP DVP 通路时,必须先通过esp_isp_new_processor创建 ISP 处理器句柄,再以该句柄创建 DVP 控制器:

#include "esp_err.h" #include "esp_cam_ctlr.h" #include "esp_cam_ctlr_isp_dvp.h" #include "driver/isp.h" #define MIPI_CSI_DISP_HSIZE 800 // example value, replace with actual resolution #define MIPI_CSI_DISP_VSIZE 600 // example value, replace with actual resolution void app_main(void) { isp_proc_handle_t isp_proc = NULL; esp_isp_processor_cfg_t isp_config = { .clk_hz = 120 * 1000 * 1000, .input_data_source = ISP_INPUT_DATA_SOURCE_DVP, .input_data_color_type = ISP_COLOR_RAW8, .output_data_color_type = ISP_COLOR_RGB565, .has_line_start_packet = false, .has_line_end_packet = false, .h_res = MIPI_CSI_DISP_HSIZE, .v_res = MIPI_CSI_DISP_VSIZE, }; ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc)); esp_cam_ctlr_handle_t cam_handle = NULL; esp_cam_ctlr_isp_dvp_cfg_t dvp_ctlr_config = { .data_width = 8, .data_io = {53, 54, 52, 0, 1, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, .pclk_io = 21, .hsync_io = 5, .vsync_io = 23, .de_io = 22, .io_flags.vsync_invert = 1, .queue_items = 10, }; ESP_ERROR_CHECK(esp_cam_new_isp_dvp_ctlr(isp_proc, &dvp_ctlr_config, &cam_handle)); }

esp_cam_ctlr_isp_dvp_cfg_t的关键字段(esp_cam_ctlr_isp_dvp.h):

  • data_width:数据线宽度(cam_ctlr_data_width_t,可取值 8/10/12/16,见 cam_ctlr_types.h);
  • data_io[16]:DVP 数据输入 IO,最多 16 路,未用引脚填-1ESP_CAM_CTLR_ISP_DVP_DATA_SIG_NUM_MAX定义为 16);
  • pclk_io/hsync_io/vsync_io/de_io:像素时钟、行同步、场同步、数据使能引脚;
  • io_flagspclk_inverthsync_invert(低有效)、vsync_invert(高有效)、de_invert(低有效),用于适配不同传感器极性;
  • queue_items:队列项数。

方式三:LCD_CAM DVP 控制器

LCD_CAM DVP 通路先配置引脚(esp_cam_ctlr_dvp_pin_config_t),再配置控制器(esp_cam_ctlr_dvp_config_t):

#include "esp_err.h" #include "esp_cam_ctlr.h" #include "esp_cam_ctlr_types.h" #include "esp_cam_ctlr_dvp.h" void app_main(void) { esp_cam_ctlr_handle_t cam_handle = NULL; esp_cam_ctlr_dvp_pin_config_t pin_cfg = { .data_width = EXAMPLE_DVP_CAM_DATA_WIDTH, .data_io = { EXAMPLE_DVP_CAM_D0_IO, EXAMPLE_DVP_CAM_D1_IO, EXAMPLE_DVP_CAM_D2_IO, EXAMPLE_DVP_CAM_D3_IO, EXAMPLE_DVP_CAM_D4_IO, EXAMPLE_DVP_CAM_D5_IO, EXAMPLE_DVP_CAM_D6_IO, EXAMPLE_DVP_CAM_D7_IO, }, .vsync_io = EXAMPLE_DVP_CAM_VSYNC_IO, .de_io = EXAMPLE_DVP_CAM_DE_IO, .pclk_io = EXAMPLE_DVP_CAM_PCLK_IO, .xclk_io = EXAMPLE_DVP_CAM_XCLK_IO, // Set XCLK pin to generate XCLK signal }; esp_cam_ctlr_dvp_config_t dvp_config = { .ctlr_id = 0, .clk_src = CAM_CLK_SRC_DEFAULT, .h_res = CONFIG_EXAMPLE_CAM_HRES, .v_res = CONFIG_EXAMPLE_CAM_VRES, .input_data_color_type = CAM_CTLR_COLOR_RGB565, .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 128, .pin = &pin_cfg, .bk_buffer_dis = 1, .xclk_freq = EXAMPLE_DVP_CAM_XCLK_FREQ_HZ, }; ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle)); }

esp_cam_ctlr_dvp_config_t的完整字段见 esp_cam_ctlr_dvp.h,要点:

  • external_xtal:置 1 时使用外部晶振产生 XCLK,此时xclk_io与驱动内部生成的输出时钟都会被忽略;否则由驱动内部生成 XCLK;
  • cam_data_width:数据位宽(8/16/24 位,默认 8);
  • bit_swap_en/byte_swap_en:位交换 / 字节交换开关,其组合效果可参考头文件内附的 GDMA 数据字节序表(以输入B0,B1,B2,B3,B4,B5、地址由低到高为例):
cam_data_widthbit_swap_enbyte_swap_en阶段 1 输出数据序列
8-bit00{B0}{B1}{B2}{B3}{B4}{B5}
8-bit01{B1,B0}{B3,B2}{B5,B4}
8-bit10{B0'}{B1'}{B2'}{B3'}{B4'}{B5'}
8-bit11{B1',B0'}{B3',B2'}{B5',B4'}
16-bit00{B1,B0}{B3,B2}{B5,B4}
16-bit01{B0,B1}{B2,B3}{B4,B5}
24-bit00{B2,B1,B0}{B5,B4,B3}
24-bit01{B0,B1,B2}{B3,B4,B5}

其中B0'表示按位取反序(Bn'[7:0] = Bn[0:7]),{}内为大端并行数据,{}之间为串行输出、从左到右。

  • bk_buffer_dis:禁用备用缓冲区;pin_dont_init:若此前已调用过esp_cam_ctlr_dvp_init,可跳过引脚初始化;pic_format_jpeg:输入为 JPEG 时置位,此时input_data_color_type会被忽略;
  • dma_burst_size:DMA 突发传输块大小,置 0 表示禁用突发,其他值必须为 2 的幂(如 4/8/16/32/64/128);
  • xclk_freq:DVP 输出时钟频率(Hz)。

创建 DVP 控制器后,需要分配满足对齐约束的相机缓冲区,可自行分配,也可调用esp_cam_ctlr_alloc_buffer自动分配(该函数必须在esp_cam_new_*_ctlr之后调用,buf_caps支持MALLOC_CAP_SPIRAM || MALLOC_CAP_DMAMALLOC_CAP_INTERNAL || MALLOC_CAP_DMA,见 esp_cam_ctlr.h)。

颜色格式枚举:三种通路共用的cam_ctlr_color_t定义于 cam_ctlr_types.h,采用 FourCC 编码,包括CAM_CTLR_COLOR_RAW8/RAW10/RAW12CAM_CTLR_COLOR_RGB565CAM_CTLR_COLOR_RGB888CAM_CTLR_COLOR_YUV420、四种 YUV422 变体(YVYU/YUYV/UYVY/VYUY)与CAM_CTLR_COLOR_GRAY8

格式转换

LCD_CAM DVP 通路支持调用esp_cam_ctlr_format_conversion配置格式转换(配置结构体cam_ctlr_format_conv_config_t,包含src_formatdst_formatconv_stddata_widthinput_rangeoutput_range,见 cam_ctlr_types.h)。驱动支持以下转换类型与色域范围:

  • 转换类型:YUV → RGB、RGB → YUV、YUV → YUV;
  • 色域范围:Full range(RGB 与 YUV 均为 0-255);Limited range(RGB 16-240,YUV Y 为 16-240、U-V 为 16-235)。

PCLK 频率限制(来自文档注意事项):

  • cam_data_width = 8时:建议 CAM_PCLK 频率低于 80 MHz;若同时启用 YUV-RGB 格式转换,建议低于 60 MHz;
  • cam_data_width = 16时:建议 CAM_PCLK 频率低于 40 MHz;若同时启用 YUV-RGB 格式转换,建议低于 30 MHz。

卸载驱动

当不再需要相机控制器时,调用esp_cam_ctlr_del释放底层硬件资源。公共层实现位于 esp_cam_ctlr.c,同样会先做空指针校验再转发到对应通路的del实现。

使能与禁用:init ↔ enable

对控制器执行任何操作前,先调用esp_cam_ctlr_enable将驱动状态从init切换到enable

#include "esp_cam_ctlr.h" #include "esp_cam_ctlr_types.h" #include "esp_err.h" void app_main(void) { esp_cam_ctlr_handle_t handle; ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle)); }

需要回到init状态时调用esp_cam_ctlr_disable

#include "esp_err.h" #include "esp_cam_ctlr.h" #include "esp_cam_ctlr_types.h" void app_main(void) { esp_cam_ctlr_handle_t handle; ESP_ERROR_CHECK(esp_cam_ctlr_disable(handle)); }

两个 API 的返回值均为ESP_OKESP_ERR_INVALID_ARG(参数非法)或ESP_ERR_INVALID_STATE(状态非法),见 esp_cam_ctlr.h。

启动与停止:enable ↔ start

开始接收相机信号前,调用esp_cam_ctlr_start将驱动状态从enable切换到start

#include "esp_err.h" #include "esp_log.h" #include "esp_cam_ctlr.h" #include "esp_cam_ctlr_types.h" void app_main(void) { esp_cam_ctlr_handle_t handle = NULL; ESP_ERROR_CHECK(esp_cam_ctlr_start(handle)); ESP_LOGI("CAM", "Camera controller started successfully"); }

停止接收并回到enable状态则调用esp_cam_ctlr_stop

#include "esp_err.h" #include "esp_cam_ctlr.h" #include "esp_cam_ctlr_types.h" void app_main(void) { esp_cam_ctlr_handle_t handle = NULL; ESP_ERROR_CHECK(esp_cam_ctlr_stop(handle)); }

由此可归纳驱动的生命周期状态机:init → enable → start,逆向依次为start → enable → init,每一层都由一对 API 完成单向切换。

接收相机数据

通过esp_cam_ctlr_receive接收来自相机传感器的数据。事务描述符类型esp_cam_ctlr_trans_t包含三个字段(esp_cam_ctlr_types.h):buffer(事务缓冲区指针)、buflen(缓冲区长度)、received_size(实际接收长度,由驱动回填):

#include "esp_err.h" #include "esp_cam_ctlr.h" #include "esp_cam_ctlr_types.h" ESP_ERROR_CHECK(esp_cam_ctlr_receive(handle, &my_trans, ESP_CAM_CTLR_MAX_DELAY));

其中ESP_CAM_CTLR_MAX_DELAY定义为UINT32_MAX(esp_cam_ctlr_types.h),表示不设超时上限;timeout_ms以毫秒为单位,可传入任意有限超时值。

注册事件回调

驱动开始接收数据后可能动态产生事件。通过esp_cam_ctlr_register_event_callbacks注册用户回调,回调集合定义于esp_cam_ctlr_evt_cbs_t(esp_cam_ctlr_types.h),包含三个回调:

  • on_get_new_trans:驱动完成一个事务并尝试获取新的事务描述符时被调用;在 CSI 通路的s_ctlr_csi_start中也会被调用。若该回调未提供新的事务描述符,且bk_buffer_dis标志未置位,驱动会使用内部备用缓冲区;
  • on_trans_finished:驱动完成一个事务时被调用。该函数运行在 ISR 上下文中,必须避免阻塞,例如只能使用带ISR后缀的 FreeRTOS API;
  • on_error:检测到错误时被调用,同样运行在 ISR 上下文,禁止调用阻塞 API。当控制器的 ISR Cache-Safe 选项使能时,该回调及其 user data 必须放在内部 RAM 中。错误事件数据esp_cam_ctlr_error_event_data_t携带csi_host_err_evts位掩码,可组合ESP_CAM_CTLR_CSI_HOST_ERR_PHY(PHY 错误)、ESP_CAM_CTLR_CSI_HOST_ERR_PACKET(数据包错误)、ESP_CAM_CTLR_CSI_HOST_ERR_FRAME(帧边界/序列错误)、ESP_CAM_CTLR_CSI_HOST_ERR_CRC(帧或负载 CRC 错误)、ESP_CAM_CTLR_CSI_HOST_ERR_DATA_ID(无法识别或不受支持的数据类型)等标志,具体枚举见 esp_cam_ctlr_types.h。

此外,若启用了内部备用缓冲区,可调用esp_cam_ctlr_get_frame_buffer/esp_cam_ctlr_get_frame_buffer_len获取内部缓冲区地址与长度——内部缓冲区的数据通常在on_trans_finished事件发生时已就绪(见 esp_cam_ctlr.h)。

线程安全

以下工厂函数是线程安全的,可以从不同的 RTOS 任务中直接调用而无需额外加锁:

  • esp_cam_new_csi_ctlrSOC_MIPI_CSI_SUPPORTED
  • esp_cam_new_isp_dvp_ctlrSOC_ISP_DVP_SUPPORTED
  • esp_cam_ctlr_del

Kconfig 配置选项

相机控制器驱动提供三个 Kconfig 选项,均位于 components/esp_driver_cam/Kconfig,用于控制缓存禁用场景下的中断行为:

选项依赖默认值作用
CAM_CTLR_MIPI_CSI_ISR_CACHE_SAFESOC_MIPI_CSI_SUPPORTEDn确保 CSI 驱动 ISR 在缓存关闭时仍可用
CAM_CTLR_ISP_DVP_ISR_CACHE_SAFESOC_ISP_DVP_SUPPORTEDn确保 ISP DVP 驱动 ISR 在缓存关闭时仍可用
CAM_CTLR_DVP_CAM_ISR_CACHE_SAFESOC_LCDCAM_CAM_SUPPORTEDn确保 DVP 驱动 ISR 在缓存关闭时仍可用

使能 CSI/ISP_DVP 的 Cache-Safe 选项后,Kconfig 会联动选择 DW_GDMA 的ISR_IRAM_SAFECTRL_FUNC_IN_IRAMSETTER_FUNC_IN_IRAMGETTER_FUNC_IN_IRAM;使能 DVP 选项后,会联动选择 GDMA 的ISR_HANDLER_IN_IRAMCTRL_FUNC_IN_IRAM(在SOC_GDMA_SUPPORTED时生效)。

IRAM Safety:缓存禁用时的中断可靠性

默认情况下,在 Flash 写入或擦除等缓存被禁用的操作期间,CSI 中断会被延迟,直到缓存重新使能后才被处理。启用上述 Cache-Safe Kconfig 选项会带来以下效果:

  • 即使缓存被禁用,中断也能得到及时服务;
  • ISR 用到的所有函数被放入 IRAM;
  • 驱动对象被放入 DRAM(避免映射到 PSRAM)。

代价是 IRAM 占用增加。在缓存关闭期间,必须确保用户回调及其相关代码/数据同样是 IRAM-Safe 或 DRAM-Safe(例如使用IRAM_ATTR修饰回调函数、将数据放在内部 RAM),否则仍可能出现取指/取数异常。

应用示例

仓库提供了三个开箱即用的完整示例(均位于 examples/peripherals/camera),演示了从采集到显示的完整链路:

  • mipi_isp_dsi:使用esp_driver_cam组件,经 ISP 模块采集 MIPI CSI 相机信号,并通过 DSI 接口在 LCD 上显示;
  • dvp_isp_dsi:使用esp_driver_cam组件,经 ISP 模块采集 DVP 相机信号,并通过 DSI 接口在 LCD 上显示;
  • dvp_dsi:使用esp_driver_cam组件采集 DVP 相机数据,并在 MIPI DSI LCD 上显示。

配套的自动化测试位于 components/esp_driver_cam/test_apps(csi / dvp / isp_dvp 三个子目录),测试代码覆盖了驱动创建、使能、收帧等核心路径,例如test_csi_ov5647.ctest_dvp_ov2640.ctest_isp_dvp_driver.c,并配有 cache_safe、pm_enable、release 等不同sdkconfig.ci.*构建配置,可帮助理解不同场景下的正确用法。

小结

相机控制器驱动通过统一的esp_cam_ctlr_handle_t句柄屏蔽了 MIPI CSI、ISP DVP、LCD_CAM DVP 三种硬件通路的差异:资源分配阶段按 SOC 能力选择对应的工厂函数并配置各自的配置结构体,运行阶段则使用同一套 enable/start/receive/stop/disable 状态机 API。需要特别留意三点:MIPI CSI 的 2.5 V 供电(必要时用内部 LDO 提供)、DVP 通路的 PCLK 频率上限(尤其开启格式转换后)、以及缓存关闭场景下通过 Cache-Safe Kconfig 选项配合 IRAM/DRAM 安全的回调代码。对上述细节的完整实现参考,可继续阅读 esp_cam_ctlr.h、esp_cam_ctlr_types.h 及各通路头文件。

【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 22:20:00

深入拆解 Lit 响应式渲染:不依赖虚拟 DOM 的组件技术解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 22:17:53

react-doctor 如何配合 git pre-commit 钩子只扫描已暂存文件

react-doctor 如何配合 git pre-commit 钩子只扫描已暂存文件 【免费下载链接】react-doctor Your agent writes bad React. This catches it 项目地址: https://gitcode.com/GitHub_Trending/re/react-doctor 你希望每次 git commit 之前,react-doctor 只检…

作者头像 李华
网站建设 2026/9/15 22:17:39

PrimeNG Dock 组件完全指南:从基础导航到模拟桌面 UI 实战

PrimeNG Dock 组件完全指南:从基础导航到模拟桌面 UI 实战 【免费下载链接】primeng The Most Complete Angular UI Component Library 项目地址: https://gitcode.com/GitHub_Trending/pr/primeng Dock 是 PrimeNG 提供的一种导航组件,由一组菜单…

作者头像 李华
网站建设 2026/9/15 22:17:29

欧姆龙E6B2编码器STM32驱动:HAL库定时器编码器模式转速读取

简介:欧姆龙E6B2编码器驱动程序基于STM32F1系列与HAL库编写,面向工业自动化和嵌入式开发者,用于精确读取编码器转速与角度,适用于速度、位置反馈控制场景。资源包共215个文件,大小仅1.29MB,主要包含C/H源码…

作者头像 李华