[应用方案] 基于APM32F407的DCI_OV2640驱动技术实现及应用

[复制链接]
 楼主| a976209770 发表于 2024-12-23 11:24 | 显示全部楼层 |阅读模式
本文将基于APM32F407微控制器和OV2640摄像头模块,讲解如何通过DCI(Digital Camera Interface)实现图像采集和传输。以下示例使用APM32F407库文件进行开发,涵盖初始化、数据采集、DMA传输及模式切换等内容。
一、OV2640 模块详细介绍

OV2640是一款功能强大的摄像头模块,具有如下特点:
  • 基本参数
    • 图像传感器:200万像素(1600x1200分辨率)
    • 输出格式:支持JPEG、RGB565、YUV等多种格式
    • 接口:SCCB(类似I2C)用于配置,DCMI(数字摄像头接口)用于数据输出
    • 模式:支持JPEG压缩模式和RGB565未压缩模式
    • 自动功能:自动曝光(AE)、自动白平衡(AWB)、自动增益(AGC)
  • 常用分辨率及格式
    • JPEG格式支持:160x120、320x240、800x600等
    • RGB565格式支持:640x480、800x600等
  • 典型应用
    • 嵌入式视觉处理
    • 安全监控
    • 图像传输
  • 控制方式OV2640通过SCCB接口配置内部寄存器(寄存器表已由用户提供),可灵活调整输出模式、分辨率、亮度、对比度等参数。
二、硬件连接及基本资源介绍

  • 硬件资源
    • 主控芯片:APM32F407
    • 摄像头模块:OV2640(支持RGB565和JPEG模式)
    • 数据接口:DCI、DMA
    • 串口:USART用于图像数据输出
    • LCD显示屏(可选)
  • DCI接口引脚DCI需要配置多个GPIO引脚,包括数据引脚(D0-D7)、控制引脚(VSYNC、HSYNC、PIXCLK)。具体定义可参考头文件bsp_dci.h。

三、流程图说明
  • 系统启动
    系统上电后,进入初始化流程。
  • 初始化流程
    包括DCI模块初始化和OV2640摄像头初始化。
  • 用户模式选择
    用户通过按键选择RGB565或JPEG模式。
  • 数据采集
    根据选择的模式,配置OV2640的工作模式,启动DCI和DMA采集。
  • 数据处理与传输
    在DCI中断中处理采集到的数据,并通过串口或其他方式输出。






四、代码实现

1.DCI初始化
通过调用DCI_Init函数完成DCI模块及相关GPIO引脚的初始化,包括时钟、同步模式和数据传输模式的配置。

  1. void DCI_Init(void)
  2. {
  3.     GPIO_Config_T gpioConfigStruct;
  4.     DCI_Config_T dciConfigStruct;

  5.     // 启用GPIO和DCI时钟
  6.     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA | RCM_AHB1_PERIPH_GPIOB | RCM_AHB1_PERIPH_GPIOC | RCM_AHB1_PERIPH_GPIOE);
  7.     RCM_EnableAHB2PeriphClock(RCM_AHB2_PERIPH_DCI);

  8.     // 配置DCI相关GPIO
  9.     gpioConfigStruct.pin = DCI_HSYNC_PIN | DCI_PIXCLK_PIN;
  10.     gpioConfigStruct.mode = GPIO_MODE_AF;
  11.     gpioConfigStruct.otype = GPIO_OTYPE_PP;
  12.     gpioConfigStruct.speed = GPIO_SPEED_100MHz;
  13.     gpioConfigStruct.pupd = GPIO_PUPD_UP;
  14.     GPIO_Config(GPIOA, &gpioConfigStruct);

  15.     // 配置DCI功能寄存器
  16.     dciConfigStruct.captureMode = DCI_CAPTURE_MODE_CONTINUOUS;
  17.     dciConfigStruct.capturerate = DCI_CAPTURE_RATE_ALL_FRAME;
  18.     dciConfigStruct.extendedDataMode = DCI_EXTENDED_DATA_MODE_8B;
  19.     dciConfigStruct.hsyncPolarity = DCI_HSYNC_POL_LOW;
  20.     dciConfigStruct.pckPolarity = DCI_PCK_POL_RISING;
  21.     dciConfigStruct.synchroMode = DCI_SYNCHRO_MODE_HARDWARE;
  22.     dciConfigStruct.vsyncPolarity = DCI_VSYNC_POL_LOW;
  23.     DCI_Config(&dciConfigStruct);

  24.     // 使能DCI中断
  25.     DCI_EnableInterrupt(DCI_INT_CC);
  26.     NVIC_EnableIRQRequest(DCI_IRQn, 0, 1);

  27.     // 启用DCI模块
  28.     DCI_Enable();
  29. }

2.摄像头初始化

摄像头模块通过SCCB接口(类似I2C)配置寄存器完成初始化,具体流程如下:

  1. uint8_t OV2640_Init(void)
  2. {
  3.     OV2640_SCCBInit(); // 初始化SCCB接口
  4.     OV2640_Reset();    // 软件复位

  5.     // 读取PID以检测摄像头是否正常
  6.     OV2640_SCCBWriteReg(DCR_DSP_RA_DLMT, 0x01);
  7.     uint16_t pid = OV2640_SCCBReadReg(DCR_SENSOR_PIDH) << 8 | OV2640_SCCBReadReg(DCR_SENSOR_PIDL);

  8.     return (pid == OV2640_PID) ? 0 : 1; // 返回初始化结果
  9. }
3.DMA配置
DCI与DMA结合使用,确保图像数据高效传输:

  1. void DCI_DMAInit(uint32_t memoryBaseAddr, uint32_t bufferSize, DMA_MEMORY_DATA_SIZE_T memoryDataSize, DMA_MEMORY_INC_T memoryInc, DMA_MEMORYBURST_T memoryBurst)
  2. {
  3.     DMA_Config_T dciDmaConfigStruct;

  4.     // 启用DMA时钟
  5.     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_DMA2);

  6.     // 配置DMA
  7.     dciDmaConfigStruct.memoryBaseAddr = memoryBaseAddr;
  8.     dciDmaConfigStruct.bufferSize = bufferSize;
  9.     dciDmaConfigStruct.memoryDataSize = memoryDataSize;
  10.     dciDmaConfigStruct.memoryInc = memoryInc;
  11.     dciDmaConfigStruct.memoryBurst = memoryBurst;
  12.     DMA_Config(DMA2_Stream1, &dciDmaConfigStruct);
  13. }

4.采集流程

摄像头模式选择后,通过DCI启动数据采集:

  1. void StartImageCapture(void)
  2. {
  3.     OV2640_JpegModeConfig(JPEG_320x240); // 设置为JPEG 320x240分辨率
  4.     DCI_DMAInit((uint32_t)&cameraBuffer, CAMERA_BUF_SIZE, DMA_MEMORY_DATA_SIZE_WORD, DMA_MEMORY_INC_ENABLE, DMA_MEMORYBURST_SINGLE);
  5.     DCI_Start(); // 启动DCI
  6. }

5.中断处理

在DCI中断中处理采集到的图像数据:

  1. void DCI_IRQHandler(void)
  2. {
  3.     if (DCI_ReadIntFlag(DCI_INT_CC) == SET)
  4.     {
  5.         if (g_ov2640Mode == JPEG_MODE)
  6.         {
  7.             OV2640_JpegDataCallback();
  8.         }
  9.         else if (g_ov2640Mode == RGB565_MODE)
  10.         {
  11.             OV2640_Rgb565DataCallback();
  12.         }

  13.         DCI_ClearIntFlag(DCI_INT_CC); // 清除中断标志
  14.     }
  15. }
6.应用示例以下为一个完整的图像采集及输出到串口的示例:

  1. void OV2640_JpegTest(void)
  2. {
  3.     // 配置摄像头和DCI
  4.     StartImageCapture();

  5.     while (1)
  6.     {
  7.         if (g_staCameraDataCaputure == 1) // 判断数据采集状态
  8.         {
  9.             for (uint32_t i = 0; i < g_cameraDataLenght; i++)
  10.             {
  11.                 USART_SendData(USART1, cameraBuffer[i]); // 将图像数据通过USART发送
  12.             }
  13.         }
  14.     }
  15. }

五、总结

通过本文的介绍,可以在APM32F407上实现DCI与OV2640的完整对接,并支持RGB565和JPEG格式的图像采集及传输。该方案适用于嵌入式视觉处理和实时监控等场景。




您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

43

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部