STM32正点原子战舰开发板驱动OV7725摄像头
CsOH_DAyy
2022年02月14日 11:31

    开发板把 OV7725 芯片采集到的图像显示到 LCD 屏的过程分为三步:OV7725 输出、FIFO 输入、FIFO 输出。下面是模块的原理图,主要有 OV7725 芯片、 AL422B  FIFO芯片和一个 SN74VC1G00  逻辑门芯片,图中红点是直接和STM32芯片连接的引脚,其它引脚是内部引脚。

模块引脚图

OV7725 图像数据输出

    OV7725 芯片配置各种寄存器通过 SCCB 标准实现,这种标准和 I²C 类似,只用到 SCL 和 SDA 两条线。

    OV7725 有两种输出模式:VGA(640 * 480)和QVGA(320 * 240),下面分别是 OV7725 输出一行和 QVGA 模式输出一帧颜色数据的写时序,一行的时序可以理解为是一帧时序的一部分。

OV7725输出一行颜色数据时序

    仔细分析上图。输出时序需要用到引脚 XCLK 、 PCLK 、 HREF 、 VSYNC 和数据线, XCLK 是24MHz的输入时钟, PCLK 是输出数据的时钟, HREF 只在输出有效数据时为高, VSYNC 在输出完一帧图像后拉高片刻。可以理解为:在 PCLK 时钟同步下,每输出完一行图像数据 HREF 置低片刻,每输出完一帧图像数据 VSYNC 置高片刻。以上信号被稍微处理后通过 PCLK 、 HREF 和数据线传给 AL422B 芯片。

AL422B 存储图像数据

    AL422B 现在有了写时钟 WCK 即 OV7725 的输出时钟 PCLK 、数据线,然而数据的时序和自己的写时序并不匹配,它现在要做的就是想办法接受得到的数据。 AL422B 重置并写数据的时序如下图。 AL422B 存储图像要用到的引脚为 WE 、 WRST 、 WCLK 和数据线。

 AL422B 重置并写时序

    可见 AL422B 每次需要连续的一帧数据,考虑到 VSYNC 信号每帧出现一次,且 HREF 信号只在 OV7725 输出有效信号时置低,因此可以利用 VSYNC 创建外部中断,每帧前发生中断,在中断里控制 WRST 信号开始接收数据,并且 WE 全程被程序和 HREF 同时控制,实现方法为一个 C=!A+!B 即 SN74VC1G00 的逻辑门,只有在程序把 FIFO_WEN 置高并且 OV7725 在输出有效数据时WE才被置低, AL422B 才继续接收数据。

    中断代码如下:

void EXTI9_5_IRQHandler( void )

{

       if ( EXTI_GetITStatus( EXTI_Line8 ) == SET )    /* 是8线的中断 */

       {

              if ( ov_sta == 0 )

              {

                     OV7725_WRST    = 0;            /* 复位写指针 */

                     OV7725_WRST    = 1;

                     OV7725_WREN    = 1;            /* 允许写入FIFO */

                     ov_sta++;                       /* 帧中断加1 */

              }else OV7725_WREN = 0;                  /* 禁止写入FIFO */

       }

       EXTI_ClearITPendingBit( EXTI_Line8 );           /* 清除EXTI8线路挂起位 */

}

AL422B 图像数据输出

    AL433B 图像数据输出只用遵循输出时序读取即可,重置并读数据的时序如下图。用到的引脚为 OE 、 RE 、 RRST 、 RCLK 和数据线, RE 和 OE 已被物理和程序上拉低。

    分析时序,得到把颜色数据显示到 LCD 屏上的代码如下。

u8 ov_sta;                                                                      /* 在exit.c里 面定义 */ /* 更新LCD显示(OV7725) */ void OV7725_camera_refresh( void ) {        u32    i, j;        u16    color;        if ( ov_sta )                                                           /* 有帧中断更新 */        {                LCD_WriteRAM_Prepare();                                         /* 开始写入GRAM */                OV7725_RRST = 0;                                                /* 开始复位读指针 */                OV7725_RCK_L;                OV7725_RCK_H;                OV7725_RCK_L;                OV7725_RRST = 1;                OV7725_RCK_H;                OV7725_RCK_L;                /* 复位读指针结束 */                for ( i = 0; i < OV7725_WINDOW_HEIGHT; i++ )                {                        for ( j = 0; j < OV7725_WINDOW_WIDTH; j++ )                        {                                color = GPIOC->IDR & 0XFF;      /* 读数据 */                                OV7725_RCK_H;                                color <<= 8;                                OV7725_RCK_L;                                color |= GPIOC->IDR & 0XFF;     /* 读数据 */                                OV7725_RCK_H;                                LCD->LCD_RAM = color;                                OV7725_RCK_L;                        }                }                ov_sta = 0;                                     /* 清零帧中断标记 */                                                      } }

参考:正点原子AN1704 ALIENTEK 摄像头模块使用、OV7725_datasheet、AL422B_datasheet。