本文将基于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引脚的初始化,包括时钟、同步模式和数据传输模式的配置。
void DCI_Init(void)
{
GPIO_Config_T gpioConfigStruct;
DCI_Config_T dciConfigStruct;
// 启用GPIO和DCI时钟
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA | RCM_AHB1_PERIPH_GPIOB | RCM_AHB1_PERIPH_GPIOC | RCM_AHB1_PERIPH_GPIOE);
RCM_EnableAHB2PeriphClock(RCM_AHB2_PERIPH_DCI);
// 配置DCI相关GPIO
gpioConfigStruct.pin = DCI_HSYNC_PIN | DCI_PIXCLK_PIN;
gpioConfigStruct.mode = GPIO_MODE_AF;
gpioConfigStruct.otype = GPIO_OTYPE_PP;
gpioConfigStruct.speed = GPIO_SPEED_100MHz;
gpioConfigStruct.pupd = GPIO_PUPD_UP;
GPIO_Config(GPIOA, &gpioConfigStruct);
// 配置DCI功能寄存器
dciConfigStruct.captureMode = DCI_CAPTURE_MODE_CONTINUOUS;
dciConfigStruct.capturerate = DCI_CAPTURE_RATE_ALL_FRAME;
dciConfigStruct.extendedDataMode = DCI_EXTENDED_DATA_MODE_8B;
dciConfigStruct.hsyncPolarity = DCI_HSYNC_POL_LOW;
dciConfigStruct.pckPolarity = DCI_PCK_POL_RISING;
dciConfigStruct.synchroMode = DCI_SYNCHRO_MODE_HARDWARE;
dciConfigStruct.vsyncPolarity = DCI_VSYNC_POL_LOW;
DCI_Config(&dciConfigStruct);
// 使能DCI中断
DCI_EnableInterrupt(DCI_INT_CC);
NVIC_EnableIRQRequest(DCI_IRQn, 0, 1);
// 启用DCI模块
DCI_Enable();
}
2.摄像头初始化
摄像头模块通过SCCB接口(类似I2C)配置寄存器完成初始化,具体流程如下:
uint8_t OV2640_Init(void)
{
OV2640_SCCBInit(); // 初始化SCCB接口
OV2640_Reset(); // 软件复位
// 读取PID以检测摄像头是否正常
OV2640_SCCBWriteReg(DCR_DSP_RA_DLMT, 0x01);
uint16_t pid = OV2640_SCCBReadReg(DCR_SENSOR_PIDH) << 8 | OV2640_SCCBReadReg(DCR_SENSOR_PIDL);
return (pid == OV2640_PID) ? 0 : 1; // 返回初始化结果
}
3.DMA配置
DCI与DMA结合使用,确保图像数据高效传输:
void DCI_DMAInit(uint32_t memoryBaseAddr, uint32_t bufferSize, DMA_MEMORY_DATA_SIZE_T memoryDataSize, DMA_MEMORY_INC_T memoryInc, DMA_MEMORYBURST_T memoryBurst)
{
DMA_Config_T dciDmaConfigStruct;
// 启用DMA时钟
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_DMA2);
// 配置DMA
dciDmaConfigStruct.memoryBaseAddr = memoryBaseAddr;
dciDmaConfigStruct.bufferSize = bufferSize;
dciDmaConfigStruct.memoryDataSize = memoryDataSize;
dciDmaConfigStruct.memoryInc = memoryInc;
dciDmaConfigStruct.memoryBurst = memoryBurst;
DMA_Config(DMA2_Stream1, &dciDmaConfigStruct);
}
4.采集流程
摄像头模式选择后,通过DCI启动数据采集:
void StartImageCapture(void)
{
OV2640_JpegModeConfig(JPEG_320x240); // 设置为JPEG 320x240分辨率
DCI_DMAInit((uint32_t)&cameraBuffer, CAMERA_BUF_SIZE, DMA_MEMORY_DATA_SIZE_WORD, DMA_MEMORY_INC_ENABLE, DMA_MEMORYBURST_SINGLE);
DCI_Start(); // 启动DCI
}
5.中断处理
在DCI中断中处理采集到的图像数据:
void DCI_IRQHandler(void)
{
if (DCI_ReadIntFlag(DCI_INT_CC) == SET)
{
if (g_ov2640Mode == JPEG_MODE)
{
OV2640_JpegDataCallback();
}
else if (g_ov2640Mode == RGB565_MODE)
{
OV2640_Rgb565DataCallback();
}
DCI_ClearIntFlag(DCI_INT_CC); // 清除中断标志
}
}
6.应用示例以下为一个完整的图像采集及输出到串口的示例:
void OV2640_JpegTest(void)
{
// 配置摄像头和DCI
StartImageCapture();
while (1)
{
if (g_staCameraDataCaputure == 1) // 判断数据采集状态
{
for (uint32_t i = 0; i < g_cameraDataLenght; i++)
{
USART_SendData(USART1, cameraBuffer[i]); // 将图像数据通过USART发送
}
}
}
}
五、总结
通过本文的介绍,可以在APM32F407上实现DCI与OV2640的完整对接,并支持RGB565和JPEG格式的图像采集及传输。该方案适用于嵌入式视觉处理和实时监控等场景。
|