458|8

10

帖子

0

资源

一粒金砂(中级)

关于使用ov7725摄像头出现花屏问题 [复制链接]

1.使用的是野火的摄像头模块,移植到龙芯1c平台的rtt系统上

2.将摄像头传输的数据显示在液晶屏上,发现出现花屏,即数据出现重复的现象 

3.一些奇怪的地方:

①可以利用硬件i2c读取和写寄存器,但是,存在部分寄存器写入失败或者压根没有写入,即我写入寄存器数值后,再次读取该寄存器的内容时,发现与我写入的数值不一致,我循环的写入之后,写入成功,再一次读取该寄存器,发现部分寄存器还是不是我期待的内容

②图像的帧率越来越低,到第27次时甚至停下了,总体上帧率也非常低(包括一开始) 

IMG_20220509_134943.jpg  

IMG_20220509_134741.jpg  

IMG_20220509_220352.jpg  


回复

10

帖子

0

资源

一粒金砂(中级)

#include "bsp_ov7725.h"

#include <rtthread.h>

#include"../libraries/ls1c_gpio.h"

#include"../libraries/ls1c_delay.h"

#include <rthw.h>

#include "mipsregs.h"

#include "ls1c.h"  

#include <stdio.h>

 

#include "GUI.h"

#include "drv_st7735.h"

#include "suse.h"

 

#include "test_tft.h"

 

#include "hw_i2c.h"

 

#define WHITE   0xffff

 

 

//以下引脚定义宏为fifo所需引脚,所配置引脚位为随意配置,具体引脚等到硬件到的时候再决定

#define OE 74

#define WRST 67

#define RRST 77

#define RCLK 59

#define WE 69

#define DATA_0 76

#define DATA_1 75

#define DATA_2 58

#define DATA_3 60

#define DATA_4 62

#define DATA_5 64

#define DATA_6 66

#define DATA_7 68

#define VSYNC 28//vsync要配置成中断模式




 

rt_uint8_t get_data(void)

{

    rt_uint8_t pic;

    rt_uint8_t buf[8];

    buf[0]=gpio_get(DATA_0);

    buf[1]=gpio_get(DATA_1);

    buf[2]=gpio_get(DATA_2);

    buf[3]=gpio_get(DATA_3);

    buf[4]=gpio_get(DATA_4);

    buf[5]=gpio_get(DATA_5);

    buf[6]=gpio_get(DATA_6);

    buf[7]=gpio_get(DATA_7);

    //for(pic=0;pic<8;pic++)

    //{

        //rt_kprintf("%d",buf[pic]);

    //}

    int i;

    for(i=0;i<8;i++)

    {

    pic |= buf<<i;  

    }

    //rt_kprintf("  ");

    //rt_kprintf("pic=ox%x ",pic);

    //rt_kprintf("pic=ox%d ",pic);

    //rt_thread_delay(6);

    return pic;

 

}

 

//摄像头初始化配置

//注意:使用这种方式初始化结构体,要在c/c++选项中选择 C99 mode

OV7725_MODE_PARAM cam_mode =

{

   

/*以下包含几组摄像头配置,可自行测试,保留一组,把其余配置注释掉即可*/

/************配置1*********横屏显示*****************************/

   

    // .QVGA_VGA = 0,   //QVGA模式

    // .cam_sx = 0,

    // .cam_sy = 0,

   

    // .cam_width = 128,

    // .cam_height = 160,

   

    // .lcd_sx = 0,

    // .lcd_sy = 0,

    // .lcd_scan = 3, //LCD扫描模式,本横屏配置可用1、3、5、7模式

   

    // //以下可根据自己的需要调整,参数范围见结构体类型定义  

    // .light_mode = 0,//自动光照模式

    // .saturation = 0,

    // .brightness = 0,

    // .contrast = 0,

    // .effect = 0,     //正常模式

   

   

/**********配置2*********竖屏显示****************************/    

/*竖屏显示需要VGA模式,同分辨率情况下,比QVGA帧率稍低*/

/*VGA模式分辨率为640*480,从中取出240*320的图像进行竖屏显示*/

/*本工程不支持超过320*240或 240*320的分辨率配置*/

 

    .QVGA_VGA = 1,  //VGA模式

    //取VGA模式居中的窗口,可根据实际需要调整

    .cam_sx = 0,

    .cam_sy = 0,    

   

    .cam_width = 128,

    .cam_height = 160, //在VGA模式下,此值才可以大于240

   

    .lcd_sx = 0,

    .lcd_sy = 0,

    .lcd_scan = 0, //LCD扫描模式,本竖屏配置可用0、2、4、6模式

   

    //以下可根据自己的需要调整,参数范围见结构体类型定义

    .light_mode = 0,//自动光照模式

    .saturation = 0,    

    .brightness = 0,

    .contrast = 0,

    .effect = 0,        //正常模式

   

   

    /*******配置3************小分辨率****************************/    

    /*小于320*240分辨率的,可使用QVGA模式,设置的时候注意液晶屏边界*/

   

    // .QVGA_VGA = 0,   //QVGA模式

    // //取QVGA模式居中的窗口,可根据实际需要调整

    // .cam_sx = 100,

    // .cam_sy = 45,    

   

    // .cam_width = 128,

    // .cam_height = 160,

   

    // /*液晶屏的显示位置也可以根据需要调整,注意不要超过边界即可*/

    // .lcd_sx = 50,

    // .lcd_sy = 50,

    // .lcd_scan = 3, //LCD扫描模式,0-7模式都支持,注意不要超过边界即可

 

    // //以下可根据自己的需要调整,参数范围见结构体类型定义  

    // .light_mode = 0,//自动光照模式

    // .saturation = 0,

    // .brightness = 0,

    // .contrast = 0,

    // .effect = 0,     //正常模式

 

};


 

typedef struct Reg

{

    rt_uint8_t Address;                /*寄存器地址*/

    rt_uint8_t Value;                  /*寄存器值*/

}Reg_Info;


 

/* 寄存器参数配置 */

Reg_Info Sensor_Config[] =

{

    {REG_CLKRC,     0x00}, /*clock config*/

    {REG_COM7,      0x46}, /*QVGA RGB565 */

    {REG_HSTART,    0x3f},

    {REG_HSIZE,     0x50},

    {REG_VSTRT,     0x03},

    {REG_VSIZE,     0x78},

    {REG_HREF,      0x00},

    {REG_HOutSize,  0x50},

    {REG_VOutSize,  0x78},

    {REG_EXHCH,     0x00},

   

 

    /*DSP control*/

    {REG_TGT_B,     0x7f},

    {REG_FixGain,   0x09},

    {REG_AWB_Ctrl0, 0xe0},

    {REG_DSP_Ctrl1, 0xff},

    {REG_DSP_Ctrl2, 0x20},

    {REG_DSP_Ctrl3, 0x00},

    {REG_DSP_Ctrl4, 0x00},

 

    /*AGC AEC AWB*/

    {REG_COM8,      0xf0},//...........................

    {REG_COM4,      0x81}, /*Pll AEC CONFIG*/

    {REG_COM6,      0xc5},

    {REG_COM9,      0x21},//............................

    {REG_BDBase,    0xFF},

    {REG_BDMStep,   0x01},

    {REG_AEW,       0x34},

    {REG_AEB,       0x3c},

    {REG_VPT,       0xa1},

    {REG_EXHCL,     0x00},

    {REG_AWBCtrl3,  0xaa},

    {REG_COM8,      0xff},

    {REG_AWBCtrl1,  0x5d},

 

    {REG_EDGE1,     0x0a},

    {REG_DNSOff,    0x01},

    {REG_EDGE2,     0x01},

    {REG_EDGE3,     0x01},

 

    {REG_MTX1,      0x5f},

    {REG_MTX2,      0x53},

    {REG_MTX3,      0x11},

    {REG_MTX4,      0x1a},

    {REG_MTX5,      0x3d},

    {REG_MTX6,      0x5a},

    {REG_MTX_Ctrl,  0x1e},

 

    {REG_BRIGHT,    0x00},

    {REG_CNST,      0x25},

    {REG_USAT,      0x65},

    {REG_VSAT,      0x65},

    {REG_UVADJ0,    0x81},

    //{REG_SDE,       0x20},    //黑白

    {REG_SDE,         0x06},    //彩色    调节SDE这个寄存器还可以实现其他效果

   

    /*GAMMA config*/

    {REG_GAM1,      0x0c},

    {REG_GAM2,      0x16},

    {REG_GAM3,      0x2a},

    {REG_GAM4,      0x4e},

    {REG_GAM5,      0x61},

    {REG_GAM6,      0x6f},

    {REG_GAM7,      0x7b},

    {REG_GAM8,      0x86},

    {REG_GAM9,      0x8e},

    {REG_GAM10,     0x97},

    {REG_GAM11,     0xa4},

    {REG_GAM12,     0xaf},

    {REG_GAM13,     0xc5},

    {REG_GAM14,     0xd7},

    {REG_GAM15,     0xe8},

    {REG_SLOP,      0x20},

 

    {REG_HUECOS,    0x80},

    {REG_HUESIN,    0x80},

    {REG_DSPAuto,   0xff},

    {REG_DM_LNL,    0x00},

    {REG_BDBase,    0x99},

    {REG_BDMStep,   0x03},

    {REG_LC_RADI,   0x00},

    {REG_LC_COEF,   0x13},

    {REG_LC_XC,     0x08},

    {REG_LC_COEFB,  0x14},

    {REG_LC_COEFR,  0x17},

    {REG_LC_CTR,    0x05},

   

    {REG_COM3,      0xd0},/*Horizontal mirror image*/

 

    /*night mode auto frame rate control*/

    //{REG_COM5,        0xf5},   /*在夜视环境下,自动降低帧率,保证低照度画面质量*/

    {REG_COM5,      0x31},  /*夜视环境帧率不变*/

};



 

rt_uint8_t OV7725_REG_NUM = sizeof(Sensor_Config)/sizeof(Sensor_Config[0]);   /*结构体数组成员数目*/

 

volatile rt_uint8_t Ov7725_vsync ;   /* 帧同步信号标志,在中断函数和main函数里面使用 */



 

/************************************************

 * 函数名:FIFO_GPIO_Config

 * 描述  :FIFO GPIO配置

 * 输入  :无

 * 输出  :无

 * 注意  :无

 ************************************************/

static void FIFO_GPIO_Config(void)

{

    //八位数据口

    gpio_init(DATA_0,gpio_mode_input);

    gpio_init(DATA_1,gpio_mode_input);

    gpio_init(DATA_2,gpio_mode_input);

    gpio_init(DATA_3,gpio_mode_input);

    gpio_init(DATA_4,gpio_mode_input);

    gpio_init(DATA_5,gpio_mode_input);

    gpio_init(DATA_6,gpio_mode_input);

    gpio_init(DATA_7,gpio_mode_input);

 

    gpio_init(OE,gpio_mode_output);

    gpio_init(WRST,gpio_mode_output);

    gpio_init(RCLK,gpio_mode_output);

    gpio_init(WE,gpio_mode_output);

 

    FIFO_OE_L();                        /*拉低使FIFO输出使能*/

    FIFO_WE_H();                        /*拉高使FIFO写允许*/


 

}

 

void  VSYNC_handle(int irq, void *param) ////vsync中断处理函数

{

    //     if ( EXTI_GetITStatus(OV7725_VSYNC_EXTI_LINE) != RESET )     //检查EXTI_Line0线路上的中断请求是否发送到了NVIC

    // {

        //rt_kprintf("vsync中断处理函数\n");

        if( Ov7725_vsync == 0 )

        {

            FIFO_WRST_L();                        //拉低使FIFO写(数据from摄像头)指针复位

            FIFO_WE_H();                            //拉高使FIFO写允许

           

            Ov7725_vsync = 1;      

            FIFO_WE_H();                          //使FIFO写允许

            FIFO_WRST_H();                        //允许使FIFO写(数据from摄像头)指针运动

        }

        else if( Ov7725_vsync == 1 )

        {

            FIFO_WE_L();                          //拉低使FIFO写暂停

            Ov7725_vsync = 2;

        }        

        // EXTI_ClearITPendingBit(OV7725_VSYNC_EXTI_LINE);          //清除EXTI_Line0线路挂起标志位        

    // }

 

}

 

/************************************************

 * 函数名:VSYNC_GPIO_Config

 * 描述  :OV7725 VSYNC中断相关配置

 * 输入  :无

 * 输出  :无

 * 注意  :无

 ************************************************/

static void VSYNC_GPIO_Config(void)

{

    //初始化vsync中断

    int VSYNC_irq = LS1C_GPIO_TO_IRQ(VSYNC);  

    gpio_set_irq_type(VSYNC, IRQ_TYPE_EDGE_FALLING);  

    rt_hw_interrupt_install(VSYNC_irq, VSYNC_handle, RT_NULL, "VSYNC");  

    rt_hw_interrupt_umask(VSYNC_irq);  

    gpio_init(VSYNC, gpio_mode_input);  

    //rt_kprintf("VSYNC interupt init succ \r\n", VSYNC_irq);

}

 

/************************************************

 * 函数名:OV7725_GPIO_Config

 * 描述  :初始化控制摄像头相接的IO

 * 输入  :无

 * 输出  :无

 * 注意  :无

 ************************************************/

void OV7725_GPIO_Config(void)

{

    i2c_Config();

    FIFO_GPIO_Config();

    VSYNC_GPIO_Config();

   

}

/**

  * @brief  ÉèÖùâÕÕ¶È

    * @param  bri:¹âÕնȣ¬²ÎÊý·¶Î§[-4~+4]

  * @retval ÎÞ

  */

void OV7725_Brightness(rt_int8_t bri)

{

    rt_uint8_t BRIGHT_Value,SIGN_Value;

   

    switch(bri)

    {

        case 4:

                BRIGHT_Value = 0x48;

                SIGN_Value = 0x06;

            break;

       

        case 3:

                BRIGHT_Value = 0x38;

                SIGN_Value = 0x06;      

        break;  

       

        case 2:

                BRIGHT_Value = 0x28;

                SIGN_Value = 0x06;          

        break;  

       

        case 1:

                BRIGHT_Value = 0x18;

                SIGN_Value = 0x06;          

        break;  

       

        case 0:

                BRIGHT_Value = 0x08;

                SIGN_Value = 0x06;          

        break;  

       

        case -1:

                BRIGHT_Value = 0x08;

                SIGN_Value = 0x0e;      

        break;  

       

        case -2:

                BRIGHT_Value = 0x18;

                SIGN_Value = 0x0e;      

        break;  

       

        case -3:

                BRIGHT_Value = 0x28;

                SIGN_Value = 0x0e;      

        break;  

       

        case -4:

                BRIGHT_Value = 0x38;

                SIGN_Value = 0x0e;      

        break;  

       

        default:

            OV7725_DEBUG("Brightness parameter error!");

            break;

    }

 

        i2c_WriteByte(REG_BRIGHT, BRIGHT_Value); //AWB on

        i2c_WriteByte(REG_SIGN, SIGN_Value);

}      

 

/************************************************

 * 函数名:Sensor_Init

 * 描述  :Sensor初始化

 * 输入  :无

 * 输出  :返回1成功,返回0失败

 * 注意  :无

 ************************************************/

int OV7725_Init(void)

{

    rt_uint16_t i = 0;

    rt_uint8_t Sensor_IDCode = 0;  

    //  if( 0 == i2c_ReadByte( &Sensor_IDCode, 1, 0x0b ) )   /* 读取sensor ID号*/

    // {

    //  rt_kprintf("read id faild\n");      

    //  //return ERROR;

    // }

    // rt_kprintf("Sensor ID is 0x%x\n", Sensor_IDCode);

    rt_kprintf("ov7725 Register Config Start......\n");

   

    if( 0 == i2c_WriteByte ( 0x12, 0x80 ) ) /*复位sensor */

    {

        rt_kprintf("sccb write data error\n");      

        return ERROR ;

    }  

    rt_thread_delay(20);

    if( 0 == i2c_ReadByte( &Sensor_IDCode, 1, 0x0b ) )   /* 读取sensor ID号*/

    {

 

        rt_kprintf("read id faild\n");      

        return ERROR;

    }

    rt_kprintf("Sensor ID is 0x%x\n", Sensor_IDCode);  

   

    if(Sensor_IDCode == OV7725_ID)

    {

        //rt_kprintf("Sensor_IDCode == OV7725_ID\n");

        for( i = 0 ; i < OV7725_REG_NUM ; i++ )

        {

           

            if( 0 == i2c_WriteByte(Sensor_Config.Address, Sensor_Config.Value) )

            {                

                rt_kprintf("write reg faild", Sensor_Config.Address);

                return ERROR;

            }

            rt_thread_delay(6);

           

            //  i2c_ReadByte( &Sensor_IDCode, 1, Sensor_Config.Address );

            //  rt_kprintf("Sensor ID is 0x%x\n", Sensor_IDCode);

            //  if(Sensor_Config.Value!=Sensor_IDCode)

            //  {

            //  rt_kprintf("write reg faild\n", Sensor_Config.Address);  

            //  }

        }

        for( i = 0 ; i < OV7725_REG_NUM ; i++ )

        {

            i2c_ReadByte( &Sensor_IDCode, 1, Sensor_Config.Address );

             rt_kprintf("reg is 0x%x\n", Sensor_IDCode);

             int cc=0;

            //  while(Sensor_Config.Value!=Sensor_IDCode)

            //  {

            //   cc++;

            //   if(cc==30)

            //   {

            //       return;

            //   }

            //    //rt_kprintf("                        write reg faild reg=%x\n", Sensor_IDCode);

            //    i2c_WriteByte(Sensor_Config.Address, Sensor_Config.Value);

            //    i2c_ReadByte( &Sensor_IDCode, 1, Sensor_Config.Address );

            //    if(Sensor_Config.Value!=Sensor_IDCode)

            //    {

            //        rt_kprintf("                   cc=%d write reg faild reg=%x\n",cc, Sensor_IDCode);

            //    }

            //    else

            //    {

            //        rt_kprintf("                   cc=%d write reg succ reg=%x\n",cc, Sensor_IDCode);

            //    }

            //  }

        }

         for( i = 0 ; i < OV7725_REG_NUM ; i++ )

         {

            i2c_ReadByte( &Sensor_IDCode, 1, Sensor_Config.Address );

            if(Sensor_Config.Value!=Sensor_IDCode)

            {

                rt_kprintf("******* write reg faild reg=%x\n", Sensor_IDCode);

            }

 

         }

         rt_kprintf("*******************************************************\n");

                 for( i = 0 ; i < OV7725_REG_NUM ; i++ )

         {

            i2c_ReadByte( &Sensor_IDCode, 1, Sensor_Config.Address );

            if(Sensor_Config.Value!=Sensor_IDCode)

            {

                rt_kprintf("******* write reg faild reg=%x\n", Sensor_IDCode);

            }

 

         }

    }

   

    else

    {

        return ERROR;

    }

    //rt_kprintf("ov7725 Register Config Success");

   

    return SUCCESS;

}

 

/**

  * @brief  设置光照模式

  * @param  mode :光照模式,参数范围[0~5]

            @arg 0:自动

            @arg 1:晴天

            @arg 2:多云

            @arg 3:办公室

            @arg 4:家里

            @arg 5:夜晚

  * @retval 无

  */

void OV7725_Light_Mode(rt_uint8_t mode)

{

    switch(mode)

    {

        case 0: //Auto,自动模式

            i2c_WriteByte(0x13, 0xff); //AWB on

            i2c_WriteByte(0x0e, 0x65);

            i2c_WriteByte(0x2d, 0x00);

            i2c_WriteByte(0x2e, 0x00);

            break;

        case 1://sunny,晴天

            i2c_WriteByte(0x13, 0xfd); //AWB off

            i2c_WriteByte(0x01, 0x5a);

            i2c_WriteByte(0x02, 0x5c);

            i2c_WriteByte(0x0e, 0x65);

            i2c_WriteByte(0x2d, 0x00);

            i2c_WriteByte(0x2e, 0x00);

            break;  

        case 2://cloudy,多云

            i2c_WriteByte(0x13, 0xfd); //AWB off

            i2c_WriteByte(0x01, 0x58);

            i2c_WriteByte(0x02, 0x60);

            i2c_WriteByte(0x0e, 0x65);

            i2c_WriteByte(0x2d, 0x00);

            i2c_WriteByte(0x2e, 0x00);

            break;  

        case 3://office,办公室

            i2c_WriteByte(0x13, 0xfd); //AWB off

            i2c_WriteByte(0x01, 0x84);

            i2c_WriteByte(0x02, 0x4c);

            i2c_WriteByte(0x0e, 0x65);

            i2c_WriteByte(0x2d, 0x00);

            i2c_WriteByte(0x2e, 0x00);

            break;  

        case 4://home,家里

            i2c_WriteByte(0x13, 0xfd); //AWB off

            i2c_WriteByte(0x01, 0x96);

            i2c_WriteByte(0x02, 0x40);

            i2c_WriteByte(0x0e, 0x65);

            i2c_WriteByte(0x2d, 0x00);

            i2c_WriteByte(0x2e, 0x00);

            break;  

       

        case 5://night,夜晚

            i2c_WriteByte(0x13, 0xff); //AWB on

            i2c_WriteByte(0x0e, 0xe5);

            break;  

       

        default:

             OV7725_DEBUG("Light Mode parameter error!");

 

            break;

    }

 

}

 

/**

  * @brief  ÉèÖñ¥ºÍ¶È

  * @param  sat:±¥ºÍ¶È,²ÎÊý·¶Î§[-4 ~ +4]                

  * @retval ÎÞ

  */

void OV7725_Color_Saturation(rt_int8_t sat)

{

 

    if(sat >=-4 && sat<=4)

    {  

        i2c_WriteByte(REG_USAT, (sat+4)<<4);

        i2c_WriteByte(REG_VSAT, (sat+4)<<4);

    }

    else

    {

        OV7725_DEBUG("Color Saturation parameter error!");

    }

   

}          

 

/**

  * @brief  设置对比度

    * @param  cnst:对比度,参数范围[-4~+4]

  * @retval 无

  */

void OV7725_Contrast(rt_int8_t cnst)

{

    if(cnst >= -4 && cnst <=4)

    {

        i2c_WriteByte(REG_CNST, (0x30-(4-cnst)*4));

    }

    else

    {

        OV7725_DEBUG("Contrast parameter error!");

    }

}

 

/**

  * @brief  设置特殊效果

    * @param  eff:特殊效果,参数范围[0~6]:

            @arg 0:正常

            @arg 1:黑白

            @arg 2:偏蓝

            @arg 3:复古

            @arg 4:偏红

            @arg 5:偏绿

            @arg 6:反相

  * @retval 无

  */

void OV7725_Special_Effect(rt_uint8_t eff)

{

    switch(eff)

    {

        case 0://正常

            i2c_WriteByte(0xa6, 0x06);

            i2c_WriteByte(0x60, 0x80);

            i2c_WriteByte(0x61, 0x80);

        break;

       

        case 1://黑白

            i2c_WriteByte(0xa6, 0x26);

            i2c_WriteByte(0x60, 0x80);

            i2c_WriteByte(0x61, 0x80);

        break;  

       

        case 2://偏蓝

            i2c_WriteByte(0xa6, 0x1e);

            i2c_WriteByte(0x60, 0xa0);

            i2c_WriteByte(0x61, 0x40);  

        break;  

       

        case 3://复古

            i2c_WriteByte(0xa6, 0x1e);

            i2c_WriteByte(0x60, 0x40);

            i2c_WriteByte(0x61, 0xa0);  

        break;  

       

        case 4://偏红

            i2c_WriteByte(0xa6, 0x1e);

            i2c_WriteByte(0x60, 0x80);

            i2c_WriteByte(0x61, 0xc0);      

        break;  

       

        case 5://偏绿

            i2c_WriteByte(0xa6, 0x1e);

            i2c_WriteByte(0x60, 0x60);

            i2c_WriteByte(0x61, 0x60);      

        break;  

       

        case 6://反相

            i2c_WriteByte(0xa6, 0x46);

        break;  

               

        default:

            OV7725_DEBUG("Special Effect error!");

            break;

    }

}      


 

/**

  * @brief  设置图像输出窗口(分辨率)QVGA

    * @param  sx:窗口x起始位置

    * @param  sy:窗口y起始位置

    * @param  width:窗口宽度

    * @param  height:窗口高度

    * @param QVGA_VGA:0,QVGA模式,1,VGA模式

  *

    * @note     QVGA模式 参数要求,sx + width <= 320 ,sy+height <= 240

    *               VGA模式参数要求,sx + width <= 640 ,sy+height <= 480

    *                   但由于 液晶屏分辨率 和 FIFO空间 的限制,本工程不适用于超过320*240的配置

    *         使用VGA模式主要是因为OV7725无法直接交换XY方向,QVGA不方便使用竖平显示,

    *                   设置成VGA模式,可以使用竖屏显示,

    *                   相对QVGA模式,同样分辨率下 VGA模式 图像采样帧率稍慢

  * @retval 无

  */

void OV7725_Window_Set(rt_uint16_t sx,rt_uint16_t sy,rt_uint16_t width,rt_uint16_t height,rt_uint8_t QVGA_VGA)

{

    rt_uint8_t reg_raw,cal_temp;

 

    /***********QVGA or VGA *************/

    if(QVGA_VGA == 0)

    {

        /*QVGA RGB565 */

        i2c_WriteByte(REG_COM7,0x46);

    }

    else

    {

            /*VGA RGB565 */

        i2c_WriteByte(REG_COM7,0x06);

    }

 

    /***************HSTART*********************/

    //读取寄存器的原内容,HStart包含偏移值,在原始偏移植的基础上加上窗口偏移    

    i2c_ReadByte(&reg_raw,1,REG_HSTART);

   

    //sx为窗口偏移,高8位存储在HSTART,低2位在HREF

    cal_temp = (reg_raw + (sx>>2));

    i2c_WriteByte(REG_HSTART,cal_temp );

   

    /***************HSIZE*********************/

    //水平宽度,高8位存储在HSIZE,低2位存储在HREF

    i2c_WriteByte(REG_HSIZE,width>>2);//HSIZE左移两位

   

   

    /***************VSTART*********************/

    //读取寄存器的原内容,VStart包含偏移值,在原始偏移植的基础上加上窗口偏移    

    i2c_ReadByte(&reg_raw,1,REG_VSTRT);

    //sy为窗口偏移,高8位存储在HSTART,低1位在HREF

    cal_temp = (reg_raw + (sy>>1));

   

    i2c_WriteByte(REG_VSTRT,cal_temp);

   

    /***************VSIZE*********************/

    //垂直高度,高8位存储在VSIZE,低1位存储在HREF

    i2c_WriteByte(REG_VSIZE,height>>1);//VSIZE左移一位

   

    /***************VSTART*********************/

    //读取寄存器的原内容

    i2c_ReadByte(&reg_raw,1,REG_HREF);  

    //把水平宽度的低2位、垂直高度的低1位,水平偏移的低2位,垂直偏移的低1位的配置添加到HREF

    cal_temp = (reg_raw |(width&0x03)|((height&0x01)<<2)|((sx&0x03)<<4)|((sy&0x01)<<6));    

   

    i2c_WriteByte(REG_HREF,cal_temp);

   

    /***************HOUTSIZIE /VOUTSIZE*********************/

    i2c_WriteByte(REG_HOutSize,width>>2);

    i2c_WriteByte(REG_VOutSize,height>>1);

   

    //读取寄存器的原内容

    i2c_ReadByte(&reg_raw,1,REG_EXHCH);

    cal_temp = (reg_raw |(width&0x03)|((height&0x01)<<2));  

 

    i2c_WriteByte(REG_EXHCH,cal_temp);  

}





 

/**

  * @brief  设置图像输出窗口(分辨率)VGA

    * @param  sx:窗口x起始位置

    * @param  sy:窗口y起始位置

    * @param  width:窗口宽度

    * @param  height:窗口高度

    * @note     本函数参数要求,sx + width <= 640 ,sy+height <= 480

    *                   但由于 液晶屏分辨率 和 FIFO空间 的限制,本工程不适用于超过320*240的配置

    *         使用本函数主要是因为OV7725无法直接交换XY方向,QVGA不方便使用竖平显示,

    *                   使用本函数设置成VGA模式,可以使用竖屏显示,

    *                   相对QVGA模式,同样分辨率下 VGA模式 图像采样帧率稍慢

  * @retval 无

  */

void OV7725_Window_VGA_Set(rt_uint16_t sx,rt_uint16_t sy,rt_uint16_t width,rt_uint16_t height)

{

   

    rt_uint8_t reg_raw,cal_temp;

 

    /***********QVGA or VGA *************/

    /*VGA RGB565 */

    i2c_WriteByte(REG_COM7,0x06);

 

    /***************HSTART*********************/

    //读取寄存器的原内容,HStart包含偏移值,在原始偏移植的基础上加上窗口偏移    

    i2c_ReadByte(&reg_raw,1,REG_HSTART);

   

    //sx为窗口偏移,高8位存储在HSTART,低2位在HREF

    cal_temp = (reg_raw + (sx>>2));

    i2c_WriteByte(REG_HSTART,cal_temp );

   

    /***************HSIZE*********************/

    //水平宽度,高8位存储在HSIZE,低2位存储在HREF

    i2c_WriteByte(REG_HSIZE,width>>2);//HSIZE左移两位 320

   

   

    /***************VSTART*********************/

    //读取寄存器的原内容,VStart包含偏移值,在原始偏移植的基础上加上窗口偏移    

    i2c_ReadByte(&reg_raw,1,REG_VSTRT);

    //sy为窗口偏移,高8位存储在HSTART,低1位在HREF

    cal_temp = (reg_raw + (sy>>1));

   

    i2c_WriteByte(REG_VSTRT,cal_temp);

   

    /***************VSIZE*********************/

    //垂直高度,高8位存储在VSIZE,低1位存储在HREF

    i2c_WriteByte(REG_VSIZE,height>>1);//VSIZE左移一位 240

   

    /***************VSTART*********************/

    //读取寄存器的原内容

    i2c_ReadByte(&reg_raw,1,REG_HREF);  

    //把水平宽度的低2位、垂直高度的低1位,水平偏移的低2位,垂直偏移的低1位的配置添加到HREF

    cal_temp = (reg_raw |(width&0x03)|((height&0x01)<<2)|((sx&0x03)<<4)|((sy&0x01)<<6));    

   

    i2c_WriteByte(REG_VSTRT,cal_temp);

   

    /***************HOUTSIZIE /VOUTSIZE*********************/

    i2c_WriteByte(REG_HOutSize,width>>2);

    i2c_WriteByte(REG_VOutSize,height>>1);

   

    //读取寄存器的原内容

    i2c_ReadByte(&reg_raw,1,REG_EXHCH);

   

    cal_temp = (reg_raw |(width&0x03)|((height&0x01)<<2));  

 

    i2c_WriteByte(REG_EXHCH,cal_temp);  

}


 

/**

  * @brief  设置显示位置

    * @param  sx:x起始显示位置

    * @param  sy:y起始显示位置

    * @param  width:显示窗口宽度,要求跟OV7725_Window_Set函数中的width一致

    * @param  height:显示窗口高度,要求跟OV7725_Window_Set函数中的height一致

  * @retval 无

  */

  rt_uint8_t pic_l;

  rt_uint8_t pic_h;

void ImagDisp(void)

{

    int i;

    rt_uint16_t RGB565;

    //LCD_Clear(WHITE);

    //rt_thread_delay(1000);

    //rt_kprintf("这里全屏变白\n");

    Lcd_SetRegion(0,0,127,159);

        for(i = 0; i < 160; i++)

        {

        for(int j=0;j<128;j++)

        {

           

                                    RGB565=0;

                                    FIFO_RCLK_L();

 

                                    pic_l=get_data();

                                    RGB565 = (pic_l) & 0xff00;

                                    FIFO_RCLK_H();

                                    FIFO_RCLK_L();

 

                                    pic_h=get_data();

                                    RGB565 |= (pic_h) & 0x00ff;

                                    //RGB565 = (pic_h <<8) | pic_l;

                                    FIFO_RCLK_H();

                                    //rt_kprintf("pic_l=%x ",pic_l);

                                    //rt_kprintf("pic_h=%x ",pic_h);

                                 //rt_kprintf("RGB565=0x%x \n",RGB565);

                    /* 从FIFO读出一个rgb565像素到Camera_Data变量 */

           

            lcd_write_data_16(RGB565);//液晶屏使用的不一样,所以这里注释掉

            //rt_thread_delay(500);

        }

        //rt_kprintf("\n");

 

        }

 

        //rt_thread_delay(3000);

}

//定义图像数组全局变量

rt_uint16_t pic[128][160]={0};

void get_pic(void)

{

    int i,j;

    rt_uint16_t Camera_Data;

    for(i=0;i<128;i++)

        for(j=0;j<160;j++)

        {

            READ_FIFO_PIXEL(Camera_Data);

            pic[j]=Camera_Data;

        }

 

}


 

void ov(void)

{

      int frame_count=0;

    tft_init();

    showimage(gImage_suse);//开机动画

    OV7725_GPIO_Config();

    int retry=0;

    while(OV7725_Init()!=SUCCESS)

    {

        retry++;

        if(retry==5)

        {

            rt_kprintf("init ov7725 failed....\n");

            return;

        }

    }

       

    OV7725_Special_Effect(cam_mode.effect);

   

    OV7725_Light_Mode(cam_mode.light_mode);

   

    OV7725_Color_Saturation(cam_mode.saturation);

   

    OV7725_Brightness(cam_mode.brightness);

   

    OV7725_Contrast(cam_mode.contrast);

   

    OV7725_Special_Effect(cam_mode.effect);

   

   

    OV7725_Window_Set(                                  cam_mode.cam_sx,

                                                        cam_mode.cam_sy,

                                                        cam_mode.cam_width,

                                                        cam_mode.cam_height,

                                                        cam_mode.QVGA_VGA);

    //OV7725_Window_VGA_Set(0,0,127,159);

    Ov7725_vsync = 0;

        while(1)

    {

       

        if( Ov7725_vsync == 2 )

        {

           frame_count++;

 

           rt_kprintf("frame_count=%d  \n",frame_count);

            if(frame_count==10)

           {return;}

            FIFO_PREPARE;                              

            ImagDisp();

            //rt_thread_delay(3000);

            rt_uint8_t Sensor_IDCode = 0;

            for(int  i = 0 ; i < OV7725_REG_NUM ; i++ )

         {

            i2c_ReadByte( &Sensor_IDCode, 1, Sensor_Config.Address );

            if(Sensor_Config.Value!=Sensor_IDCode)

            {

                rt_kprintf("******* write reg faild reg=%x\n", Sensor_IDCode);

            }

 

         }

            Ov7725_vsync = 0;          

            //LED1_TOGGLE;

 

        }

    }

   

 

}

 

MSH_CMD_EXPORT(ov, ov7725 test);

 


回复

2019

帖子

0

资源

五彩晶圆(初级)

建议你用逻辑分析仪看看I2C的数据是否正常

点评

每次都是一些寄存器有问题,写成功后再读又变成错的了 [attachimg]604763[/attachimg]    详情 回复 发表于 2022-5-10 11:08

回复

10

帖子

0

资源

一粒金砂(中级)

IC爬虫 发表于 2022-5-10 10:11 建议你用逻辑分析仪看看I2C的数据是否正常

每次都是一些寄存器有问题,写成功后再读又变成错的了

image.png  

点评

那就先查为啥会出错,看看是不是固定的几个寄存器的问题还是随机出现的,查I2C的问题第一步就是看I2C的收发是否正常,是否有干扰…… (上逻辑分析仪,盲调是不行的)  详情 回复 发表于 2022-5-10 11:24

回复

2019

帖子

0

资源

五彩晶圆(初级)

xycgood 发表于 2022-5-10 11:08 每次都是一些寄存器有问题,写成功后再读又变成错的了  

那就先查为啥会出错,看看是不是固定的几个寄存器的问题还是随机出现的,查I2C的问题第一步就是看I2C的收发是否正常,是否有干扰……

(上逻辑分析仪,盲调是不行的)


回复

10

帖子

0

资源

一粒金砂(中级)

是的,每次都是固定几个寄存器的问题,害,难整

 

点评

如果是固定的的寄存器问题,那就检测sensor的寄存器配置列表是否正常? 另外你怎么知道你写的寄存器是错的?sensor的寄存器有些配置一个初值后,自己是变的的,并不是你开始写的那个值,比如曝光、增益等寄存器  详情 回复 发表于 2022-5-10 11:47

回复

2019

帖子

0

资源

五彩晶圆(初级)

xycgood 发表于 2022-5-10 11:42 是的,每次都是固定几个寄存器的问题,害,难整  

如果是固定的的寄存器问题,那就检测sensor的寄存器配置列表是否正常?

另外你怎么知道你写的寄存器是错的?sensor的寄存器有些配置一个初值后,自己是变的的,并不是你开始写的那个值,比如曝光、增益等寄存器


回复

10

帖子

0

资源

一粒金砂(中级)

有些寄存器会自动改变吗,那或许不是寄存器写错的原因了,可是如果不是这个原因的话,在正确写入了寄存器之后,为什么输出的数值(rgb565)成周期性变化,这个变化与摄像头照到的景象不相关

P9C@83EODVY`JE6RA}9)M0P.png  


回复

9713

帖子

21

资源

版主

上拉电阻都焊接了吗 连线有多长?我觉得应该重点检查I2C通信 用示波器看看波形是不是都正常


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

查找数据手册?

EEWorld Datasheet 技术支持

最新文章 更多>>
    推荐帖子
    Qt学习之路第38篇 存储容器

    存储容器(containers)有时候也被称为集合(collections),是能够在内存中存储其它特定类型的对象,通常是一些常用的数据结构 ...

    关于74HC14输入脚的问题

    请问大家74HC14输入脚的最大电压是多少?从手册上看不出来呀,图上有个D.U.T被测设备,不知道其中的结构是什么样的?

    tftp网络烧录系统

    问: setenv bootargs 'console=ttymxc0,115200 rdinit=/etc/inittab enable_wait_mode=off' bootm 0x10800000 0x10c00000 ...

    X-NUCLEO-IKS01A3的应用尝试

    在各个传感器都测试了一遍之后,便开始着手应用的尝试,首先是准备将传感器的数据集中显示,由于显示屏太小,只得分屏显示,第 ...

    CLUE 徽章

    462711 使用Adafruit CircuitPython PyBadger库很容易将您的CLUE变成自定义会议或活动徽章。PyBadger的自定义标志功能使在彩 ...

    【IoT毕业设计】树莓派开发板+机智云IoT+监测机器人

    本帖最后由 毛球大大 于 2022-4-27 18:00 编辑 摘要:以小车为基底,以树莓派开发板为中心,搭载摄像头、传感器等数据采集设备 ...

    关闭
    站长推荐上一条 1/9 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表