关于OV7670不带FIFO读不出来ID问题讨论

一下是我的代码,总感觉没有问题但是就是无法读取OV7670不带FIFO的ID。

我使用的是CH32V307V板子。

有哪位好心人可以帮我看一下哪里除了问题

  • SCCB.h
#ifndef COMLIB_OV7670_SCCB_SOFTWARE_SCCB_H_
#define COMLIB_OV7670_SCCB_SOFTWARE_SCCB_H_

#include "stdio.h"

/* 引脚定义 */
#define SCCB_PORT GPIOA
#define SCCB_RCC  RCC_APB2Periph_GPIOA
#define SCCB_SCL  GPIO_Pin_0
#define SCCB_SDA  GPIO_Pin_1

/* 设备地址 */
#define SCCB_ID 0x43

/* SDA引脚的高低变换 */
//#define SCCB_SDA_SET GPIO_WriteBit(SCCB_PORT, SCCB_SDA, Bit_SET)
//#define SCCB_SDA_CLR GPIO_WriteBit(SCCB_PORT, SCCB_SDA, Bit_RESET)
#define SCCB_SET_SDA(x)       GPIO_WriteBit(SCCB_PORT, SCCB_SDA, (BitAction)(x))

/* SDA引脚的状态 */
#define SCCB_SDA_STATE GPIO_ReadInputDataBit(SCCB_PORT, SCCB_SDA)

/* SCL引脚的高低变换 */
//#define SCCB_SCL_SET GPIO_WriteBit(SCCB_PORT, SCCB_SCL, Bit_SET)
//#define SCCB_SCL_CLR GPIO_WriteBit(SCCB_PORT, SCCB_SCL, Bit_RESET)
#define SCCB_SET_SCL(x)       GPIO_WriteBit(SCCB_PORT, SCCB_SCL, (BitAction)(x))

void SCCB_Init();   // SCCB初始化

void SCCB_Start();  // SCCB开始
void SCCB_Stop();   // SCCB结束

void SCCB_NO_Ack();     // SCCB应答信号

void SCCB_SDA_OUT();    // SDA输出
void SCCB_SDA_IN();     // SDA输入

uint8_t SCCB_Write_Byte(uint8_t data);  // 写一个字节
uint8_t SCCB_Read_Byte(void);     // 读取一个字节

uint8_t SCCB_Write_Reg(uint8_t reg, uint8_t data); // 向寄存器写数据
uint8_t SCCB_Read_Reg(uint8_t reg); // 读取寄存器数据

#endif /* COMLIB_OV7670_SCCB_SOFTWARE_SCCB_H_ */
  • SCCB.c
#include "ch32v30x_gpio.h"
#include "ch32v30x_rcc.h"
#include "SoftWare_SCCB.h"
#include "stdio.h"
#include "Delay.h"
#include "OLED1306.h"
/*
 * 初始化
 *  1.设置SCCB_SDA
 *  2.设置SCCB_SCL
 */
void SCCB_Init() {
    GPIO_InitTypeDef GPIO_InitStructure = { 0 };

    RCC_APB2PeriphClockCmd(SCCB_RCC, ENABLE);

    GPIO_InitStructure.GPIO_Pin = SCCB_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SCCB_PORT, &GPIO_InitStructure);
    GPIO_SetBits(SCCB_PORT, SCCB_SDA);

    GPIO_InitStructure.GPIO_Pin = SCCB_SCL;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SCCB_PORT, &GPIO_InitStructure);
    GPIO_SetBits(SCCB_PORT, SCCB_SCL);

    SCCB_SDA_OUT();
}

/*
 * 设置SCCB_SDA引脚输出
 */
void SCCB_SDA_OUT() {
    GPIO_InitTypeDef GPIO_InitStructure = { 0 };

    RCC_APB2PeriphClockCmd(SCCB_RCC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = SCCB_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SCCB_PORT, &GPIO_InitStructure);
    GPIO_SetBits(SCCB_PORT, SCCB_SDA);
}

/*
 * 设置SCCB_SDA引脚输入
 */
void SCCB_SDA_IN() {
    GPIO_InitTypeDef GPIO_InitStructure = { 0 };

    RCC_APB2PeriphClockCmd(SCCB_RCC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = SCCB_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SCCB_PORT, &GPIO_InitStructure);
    GPIO_SetBits(SCCB_PORT, SCCB_SDA);
}

/*
 * SCCB_SDA在SCCB_SCL高电平时由高电平到低电平
 */
void SCCB_Start() {
    SCCB_SET_SDA(1);
    SCCB_SET_SCL(1);
    Delay_Us(50);
    SCCB_SET_SDA(0);
    Delay_Us(50);
    SCCB_SET_SCL(0);
}

/*
 * SCCB_SDA在SCCB_SCL高电平时由低电平到高电平
 */
void SCCB_Stop() {
    SCCB_SET_SDA(0);
    Delay_Us(50);
    SCCB_SET_SCL(1);
    Delay_Us(50);
    SCCB_SET_SDA(1);
    Delay_Us(50);
}

void SCCB_NO_Ack() {
    Delay_Us(50);
    SCCB_SET_SDA(1);
    SCCB_SET_SCL(1);
    Delay_Us(50);
    SCCB_SET_SCL(0);
    Delay_Us(50);
    SCCB_SET_SDA(0);
    Delay_Us(50);
}

uint8_t SCCB_Write_Byte(unsigned char data) {
    uint8_t i, res;
    res = 0;
    for (i = 0; i < 8; i++) { //循环8次发送数据
        if (data & 0x80) {
            SCCB_SET_SDA(1);
        } else {
            SCCB_SET_SDA(0);
        }
        data = data << i;
        Delay_Us(50);
        SCCB_SET_SCL(1);
        Delay_Us(50);
        SCCB_SET_SCL(0);
    }
    SCCB_SDA_IN();
    Delay_Us(50);
    SCCB_SET_SCL(1);
    Delay_Us(50);
    /*
     * SDA=0发送成功,返回1
     * SDA=1发送失败,返回0
     */

    if (SCCB_SDA_STATE) {

        res = 1;
    } else {
        res = 0;
    }

    SCCB_SET_SCL(0);
    SCCB_SDA_OUT();

    return res;
}

uint8_t SCCB_Read_Byte() {
    unsigned char read, i;
    read = 0x00;
    SCCB_SDA_IN();
    for (i = 8; i > 0; i--) {
        Delay_Us(50);
        SCCB_SET_SCL(1);
        read = read << 1;
        if (SCCB_SDA_STATE) {
            read = read + 1;
        }
        Delay_Us(50);
        SCCB_SET_SCL(0);
    }
    SCCB_SDA_OUT();
    return read;
}

/*
 * 向寄存器写数据
 */
uint8_t SCCB_Write_Reg(uint8_t reg, uint8_t data) {
    uint8_t res;
    res = 0;
    SCCB_Start();
    if (SCCB_Write_Byte(SCCB_ID)) {
        res = 1;
    }
    Delay_Us(100);
    if (SCCB_Write_Byte(reg)) {
        res = 1;
    }
    Delay_Us(100);
    if (SCCB_Write_Byte(data)) {
        res = 1;
    }
    SCCB_Stop();
    return res;
}

/*
 * 向寄存器读数据
 */
uint8_t SCCB_Read_Reg(uint8_t reg) {
    uint8_t read;
    read = 0x00;
    SCCB_Start();
    SCCB_Write_Byte(SCCB_ID);
    Delay_Us(100);
    SCCB_Write_Byte(reg);
    Delay_Us(100);
    SCCB_Stop();
    Delay_Us(100);
    SCCB_Start();
    SCCB_Write_Byte(SCCB_ID | 0x01);
    Delay_Us(100);
    read = SCCB_Read_Byte();
    SCCB_NO_Ack();
    SCCB_Stop();
    return read;
}
  • OV7670.h
#ifndef COMLIB_OV7670_OV7670_OV7670_H_
#define COMLIB_OV7670_OV7670_OV7670_H_

#include "stdio.h"

//VSYNC     PA2        (帧同步信号:out)
//HREF      PA3         (行同步信号:out)
//XCLK      PA8         (时钟信号:in)
//PCLK      PA4         (像素时钟:out)
//PWDN      PA9         (功耗选择模式  0工作 1POWER DOWN)正常使用拉低,该引脚与JTDO连接,需先关闭
//RESET     PA10        (复位端:0RESET 1一般模式 )正常使用拉高
//SIOC      PA0
//SIOD      PA1
//D?        P0~P7   (数据位)


#define OV7670_DATA   GPIO_ReadInputData(GPIOC,0x00FF)                  //数据输入端口

u8   OV7670_Init(void);

void OV7670_Window_Set(u16 sx,u16 sy,u16 width,u16 height);
void CLK_init_ON(void);
void CLK_init_OFF(void);

#endif /* COMLIB_OV7670_OV7670_OV7670_H_ */
  • OV7670.c
#include "ch32v30x_gpio.h"
#include "ch32v30x_rcc.h"
#include "OV7670.h"
#include "OV7670_cfg.h"
#include "Delay.h"
#include "SoftWare_SCCB.h"
#include "OLED1306.h"
#include "stdio.h"

//VSYNC     PA2        (帧同步信号:out)
//HREF      PA3         (行同步信号:out)
//XCLK      PA8         (时钟信号:in)
//PCLK      PA4         (像素时钟:out)
//PWDN      PA9         (功耗选择模式  0工作 1POWER DOWN)正常使用拉低,该引脚与JTDO连接,需先关闭
//RESET     PA10        (复位端:0RESET 1一般模式 )正常使用拉高
//SIOC      PA0
//SIOD      PA1



//初始化OV7670
//返回0:成功
//返回其他值:错误代码
u8 OV7670_Init(void)
{
    OLED1306_ShowString(4, 4, "INIT");
    u8 temp;
    u16 i=0;

    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);    //使能相关端口时钟

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2;     //PG15 输入 上拉                    VSYNC
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;          //PB4  端口配置          PCLK
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_4);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3;      //PD6       HREF
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_3);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                //PB3 端口配置         PWDN  正常使用拉低
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOA,GPIO_Pin_9);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;         //PG14  RESET       正常使用拉高
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_10);


    GPIO_InitStructure.GPIO_Pin  = 0xff; //PC0~7 输入 上拉          D0~8
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;       //GPIO_Mode_IPU;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    CLK_init_ON();

    SCCB_Init();                //初始化SCCB 的IO口
    if(SCCB_Write_Reg(0x12,0x80)){
//        return 1; //复位SCCB
    }
    Delay_Ms(50);
    temp=SCCB_Read_Reg(0x12);
    //读取产品型号
    temp=SCCB_Read_Reg(0x0b);
    OLED1306_ShowNum(2, 2, temp, 4);
    if(temp!=0x73){
//        return 2;
    }
    temp=SCCB_Read_Reg(0x0a);
    if(temp!=0x76){
//        return 2;
    }
    //初始化序列   对OV7670寄存器进行操作
    for(i=0;i<sizeof(ov7670_init_reg_tbl)/sizeof(ov7670_init_reg_tbl[0])/2;i++)
    {
        SCCB_Write_Reg(ov7670_init_reg_tbl[i][0],ov7670_init_reg_tbl[i][1]);
        Delay_Ms(2);
    }
    return 0x00;
}

void CLK_init_ON(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);      //HSE是高速外部时钟,频率范围为4MHz~16MHz   实测出来为8MHz
    RCC_MCOConfig(RCC_MCO_HSE  );//hsi  Selects the clock source to output on MCO pin.   RCC_MCO_HSE: HSE oscillator clock selected
}
void CLK_init_OFF(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}



//设置图像输出窗口
//对QVGA设置。
void OV7670_Window_Set(u16 sx,u16 sy,u16 width,u16 height)
{
    u16 endx;
    u16 endy;
    u8 temp;
    endx=sx+width*2;    //V*2
    endy=sy+height*2;
    if(endy>784)endy-=784;
    temp=SCCB_Read_Reg(0X03);             //读取Vref之前的值
    temp&=0XF0;
    temp|=((endx&0X03)<<2)|(sx&0X03);
    SCCB_Write_Reg(0X03,temp);             //设置Vref的start和end的最低2位
    SCCB_Write_Reg(0X19,sx>>2);            //设置Vref的start高8位
    SCCB_Write_Reg(0X1A,endx>>2);          //设置Vref的end的高8位

    temp=SCCB_Read_Reg(0X32);             //读取Href之前的值
    temp&=0XC0;
    temp|=((endy&0X07)<<3)|(sy&0X07);
    SCCB_Write_Reg(0X17,sy>>3);            //设置Href的start高8位
    SCCB_Write_Reg(0X18,endy>>3);          //设置Href的end的高8位
}



//OV7670功能设置
//白平衡设置
//0:自动
//1:太阳sunny
//2,阴天cloudy
//3,办公室office
//4,家里home
void OV7670_Light_Mode(u8 mode)
{
    u8 reg13val=0XE7;//默认就是设置为自动白平衡
    u8 reg01val=0;
    u8 reg02val=0;
    switch(mode)
    {
        case 1://sunny
            reg13val=0XE5;
            reg01val=0X5A;
            reg02val=0X5C;
            break;
        case 2://cloudy
            reg13val=0XE5;
            reg01val=0X58;
            reg02val=0X60;
            break;
        case 3://office
            reg13val=0XE5;
            reg01val=0X84;
            reg02val=0X4c;
            break;
        case 4://home
            reg13val=0XE5;
            reg01val=0X96;
            reg02val=0X40;
            break;
    }
    SCCB_Write_Reg(0X13,reg13val);//COM8设置
    SCCB_Write_Reg(0X01,reg01val);//AWB蓝色通道增益
    SCCB_Write_Reg(0X02,reg02val);//AWB红色通道增益
}
//色度设置
//0:-2
//1:-1
//2,0
//3,1
//4,2
void OV7670_Color_Saturation(u8 sat)
{
    u8 reg4f5054val=0X80;//默认就是sat=2,即不调节色度的设置
    u8 reg52val=0X22;
    u8 reg53val=0X5E;
    switch(sat)
    {
        case 0://-2
            reg4f5054val=0X40;
            reg52val=0X11;
            reg53val=0X2F;
            break;
        case 1://-1
            reg4f5054val=0X66;
            reg52val=0X1B;
            reg53val=0X4B;
            break;
        case 3://1
            reg4f5054val=0X99;
            reg52val=0X28;
            reg53val=0X71;
            break;
        case 4://2
            reg4f5054val=0XC0;
            reg52val=0X33;
            reg53val=0X8D;
            break;
    }
    SCCB_Write_Reg(0X4F,reg4f5054val); //色彩矩阵系数1
    SCCB_Write_Reg(0X50,reg4f5054val); //色彩矩阵系数2
    SCCB_Write_Reg(0X51,0X00);         //色彩矩阵系数3
    SCCB_Write_Reg(0X52,reg52val);     //色彩矩阵系数4
    SCCB_Write_Reg(0X53,reg53val);     //色彩矩阵系数5
    SCCB_Write_Reg(0X54,reg4f5054val); //色彩矩阵系数6
    SCCB_Write_Reg(0X58,0X9E);         //MTXS
}
//亮度设置
//0:-2
//1:-1
//2,0
//3,1
//4,2
void OV7670_Brightness(u8 bright)
{
    u8 reg55val=0X00;//默认就是bright=2
    switch(bright)
    {
        case 0://-2
            reg55val=0XB0;
            break;
        case 1://-1
            reg55val=0X98;
            break;
        case 3://1
            reg55val=0X18;
            break;
        case 4://2
            reg55val=0X30;
            break;
    }
    SCCB_Write_Reg(0X55,reg55val); //亮度调节
}
//对比度设置
//0:-2
//1:-1
//2,0
//3,1
//4,2
void OV7670_Contrast(u8 contrast)
{
    u8 reg56val=0X40;//默认就是contrast=2
    switch(contrast)
    {
        case 0://-2
            reg56val=0X30;
            break;
        case 1://-1
            reg56val=0X38;
            break;
        case 3://1
            reg56val=0X50;
            break;
        case 4://2
            reg56val=0X60;
            break;
    }
    SCCB_Write_Reg(0X56,reg56val); //对比度调节
}
//特效设置
//0:普通模式
//1,负片
//2,黑白
//3,偏红色
//4,偏绿色
//5,偏蓝色
//6,复古
void OV7670_Special_Effects(u8 eft)
{
    u8 reg3aval=0X04;//默认为普通模式
    u8 reg67val=0XC0;
    u8 reg68val=0X80;
    switch(eft)
    {
        case 1://负片
            reg3aval=0X24;
            reg67val=0X80;
            reg68val=0X80;
            break;
        case 2://黑白
            reg3aval=0X14;
            reg67val=0X80;
            reg68val=0X80;
            break;
        case 3://偏红色
            reg3aval=0X14;
            reg67val=0Xc0;
            reg68val=0X80;
            break;
        case 4://偏绿色
            reg3aval=0X14;
            reg67val=0X40;
            reg68val=0X40;
            break;
        case 5://偏蓝色
            reg3aval=0X14;
            reg67val=0X80;
            reg68val=0XC0;
            break;
        case 6://复古
            reg3aval=0X14;
            reg67val=0XA0;
            reg68val=0X40;
            break;
    }
    SCCB_Write_Reg(0X3A,reg3aval);//TSLB设置
    SCCB_Write_Reg(0X68,reg67val);//MANU,手动U值
    SCCB_Write_Reg(0X67,reg68val);//MANV,手动V值
}


/*
//更新LCD显示
void camera_refresh(void)
{
    u32 i,j;
    u16 color;

        LCD_Scan_Dir(U2D_L2R);      //从上到下,从左到右
        LCD_SetCursor(0x00,0x0000); //设置光标位置
        LCD_WriteRAM_Prepare();     //开始写入GRAM

        while(OV7670_VSYNC==0);//0-1
    while(OV7670_VSYNC==1);//1-0        只有在VSYNC为低时,才传输数据

        //240*320=76800    又每个像素用RGB565表示,即每个像素占用两个字节(16位数据)  I2C一次传输8位数据 故一个像素要传2次
        //将读取到的数据按RGB565的处理,保存到一个16位(color)变量中
    for(i=0;i<240;i++)
    {
        while(OV7670_HREF==0);//0-1 只有在HREF为高时,才传输数据
        for(j=0;j<320;j++)
        {

            //读取高8位
            while(OV7670_PCLK==0);          //0-1           数据在PCLK上升沿保持稳定,在此时读取数据
            color=GPIOC->IDR&0XFF;  //读数据
            while(OV7670_PCLK==1);      //1-0
            //左移高八位
            color<<=8;
            //读取低8位
            while(OV7670_PCLK==0);          //0-1
            color|=GPIOC->IDR&0XFF; //读数据
            while(OV7670_PCLK==1);      //1-0
            //显示LCD
            LCD->LCD_RAM=color;
        }
        while(OV7670_HREF==1); //1-0
    }
    LCD_Scan_Dir(DFT_SCAN_DIR); //恢复默认扫描方向
}
*/


  • OV7670_cfg.h
#ifndef COMLIB_OV7670_OV7670_OV7670_CFG_H_
#define COMLIB_OV7670_OV7670_OV7670_CFG_H_

#include "stdio.h"

//初始化寄存器序列及其对应的值
const u8 ov7670_init_reg_tbl[][2]=
{
     //以下为OV7670 QVGA RGB565参数
    {0x3a, 0x04},   //
    {0x40, 0x10},  //设置数据位RGB565 00-FF
    //{0x40, 0xd0},
    {0x12, 0x14},//QVGA,RGB输出******************************************

    //输出窗口设置
    {0x32, 0x80},
    {0x17, 0x16},
    {0x18, 0x04},//5
    {0x19, 0x02},
    {0x1a, 0x7a},//0x7a,
    {0x03, 0x0a},//0x0a,


    {0x0c, 0x0c},
    {0x15, 0x00},
    {0x3e, 0x00},//10       pclk不分频
    {0x70, 0x00},
    {0x71, 0x01},
    {0x72, 0x11},
    {0x73, 0x09},//

    {0xa2, 0x02},//15
    {0x11, 0x04},//内部时钟分频设置,0,不分频.*******************************************************04
    {0x7a, 0x20},  //@0x12
    {0x7b, 0x1c},
    {0x7c, 0x28},

    {0x7d, 0x3c},//20
    {0x7e, 0x55},
    {0x7f, 0x68},
    {0x80, 0x76},
    {0x81, 0x80},

    {0x82, 0x88},
    {0x83, 0x8f},
    {0x84, 0x96},
    {0x85, 0xa3},
    {0x86, 0xaf},

    {0x87, 0xc4},//30
    {0x88, 0xd7},
    {0x89, 0xe8},
    {0x13, 0xe0},//@(0xe4)使能AGC
    {0x00, 0x00},//AGC

    {0x10, 0x00},
    {0x0d, 0x00},
    {0x14, 0x20},//0x38, limit the max gain
    {0xa5, 0x05},
    {0xab, 0x07},

    {0x24, 0x75},//40
    {0x25, 0x63},
    {0x26, 0xA5},
    {0x9f, 0x78},
    {0xa0, 0x68},

    {0xa1, 0x03},//0x0b,
    {0xa6, 0xdf},//0xd8,
    {0xa7, 0xdf},//0xd8,
    {0xa8, 0xf0},
    {0xa9, 0x90},

    {0xaa, 0x94},//50
    {0x13, 0xe5},
    {0x0e, 0x61},
    {0x0f, 0x4b},
    {0x16, 0x02},

    {0x1e, 0x17},//图像输出镜像控制.0x07,  0x37水平镜像+竖直翻转 0x27
    {0x21, 0x02},
    {0x22, 0x91},
    {0x29, 0x07},
    {0x33, 0x0b},

    {0x35, 0x0b},//60
    {0x37, 0x1d},
    {0x38, 0x71},
    {0x39, 0x2a},
    {0x3c, 0x78},

    {0x4d, 0x40},
    {0x4e, 0x20},
    {0x69, 0x5d},
    {0x6b, 0x40},//PLL*4=48Mhz           40
    {0x74, 0x19},
    {0x8d, 0x4f},

    {0x8e, 0x00},//70
    {0x8f, 0x00},
    {0x90, 0x00},
    {0x91, 0x00},
    {0x92, 0x00},//0x19,//0x66

    {0x96, 0x00},
    {0x9a, 0x80},
    {0xb0, 0x84},
    {0xb1, 0x0c},
    {0xb2, 0x0e},

    {0xb3, 0x82},//80
    {0xb8, 0x0a},
    {0x43, 0x14},
    {0x44, 0xf0},
    {0x45, 0x34},

    {0x46, 0x58},
    {0x47, 0x28},
    {0x48, 0x3a},
    {0x59, 0x88},
    {0x5a, 0x88},

    {0x5b, 0x44},//90
    {0x5c, 0x67},
    {0x5d, 0x49},
    {0x5e, 0x0e},
    {0x64, 0x04},
    {0x65, 0x20},

    {0x66, 0x05},
    {0x94, 0x04},
    {0x95, 0x08},
    {0x6c, 0x0a},
    {0x6d, 0x55},


    {0x4f, 0x80},
    {0x50, 0x80},
    {0x51, 0x00},
    {0x52, 0x22},
    {0x53, 0x5e},
    {0x54, 0x80},

    //{0x54, 0x40},//110


    {0x09, 0x03},//驱动能力最大

    {0x6e, 0x11},//100
    {0x6f, 0x9f},//0x9e for advance AWB
    {0x55, 0x00},//亮度
    {0x56, 0x40},//对比度
    {0x57, 0x80},//0x40,  change according to Jim's request
};

//初始化寄存器序列及其对应的值
const u8 ov7670_init_reg_tb2[][2]=
{
    /*以下为OV7670 QVGA RGB565参数  */
    {0x3a, 0x04},//dummy
    {0x40, 0xd0},//565
    {0x12, 0x14},//QVGA,RGB输出

    //输出窗口设置
    {0x32, 0x80},//HREF control bit[2:0] HREF start 3 LSB    bit[5:3] HSTOP HREF end 3LSB
    {0x17, 0x16},//HSTART start high 8-bit MSB
    {0x18, 0x04},//5 HSTOP end high 8-bit
    {0x19, 0x02},
    {0x1a, 0x7b},//0x7a,
    {0x03, 0x06},//0x0a,帧竖直方向控制

    {0x0c, 0x00},
    {0x15, 0x00},//0x00
    {0x3e, 0x00},//10
    {0x70, 0x3a},
    {0x71, 0x35},
    {0x72, 0x11},
    {0x73, 0x00},//

    {0xa2, 0x02},//15
    {0x11, 0x81},//时钟分频设置,0,不分频.
    {0x7a, 0x20},
    {0x7b, 0x1c},
    {0x7c, 0x28},

    {0x7d, 0x3c},//20
    {0x7e, 0x55},
    {0x7f, 0x68},
    {0x80, 0x76},
    {0x81, 0x80},

    {0x82, 0x88},
    {0x83, 0x8f},
    {0x84, 0x96},
    {0x85, 0xa3},
    {0x86, 0xaf},

    {0x87, 0xc4},//30
    {0x88, 0xd7},
    {0x89, 0xe8},
    {0x13, 0xe0},
    {0x00, 0x00},//AGC

    {0x10, 0x00},
    {0x0d, 0x00},//全窗口, 位[5:4]: 01 半窗口,10 1/4窗口,11 1/4窗口
    {0x14, 0x28},//0x38, limit the max gain
    {0xa5, 0x05},
    {0xab, 0x07},

    {0x24, 0x75},//40
    {0x25, 0x63},
    {0x26, 0xA5},
    {0x9f, 0x78},
    {0xa0, 0x68},

    {0xa1, 0x03},//0x0b,
    {0xa6, 0xdf},//0xd8,
    {0xa7, 0xdf},//0xd8,
    {0xa8, 0xf0},
    {0xa9, 0x90},

    {0xaa, 0x94},//50
    {0x13, 0xe5},
    {0x0e, 0x61},
    {0x0f, 0x4b},
    {0x16, 0x02},

    {0x1e, 0x27},//图像输出镜像控制.0x07
    {0x21, 0x02},
    {0x22, 0x91},
    {0x29, 0x07},
    {0x33, 0x0b},

    {0x35, 0x0b},//60
    {0x37, 0x1d},
    {0x38, 0x71},
    {0x39, 0x2a},
    {0x3c, 0x78},

    {0x4d, 0x40},
    {0x4e, 0x20},
    {0x69, 0x00},
    {0x6b, 0x40},//PLL*4=48Mhz
    {0x74, 0x19},
    {0x8d, 0x4f},

    {0x8e, 0x00},//70
    {0x8f, 0x00},
    {0x90, 0x00},
    {0x91, 0x00},
    {0x92, 0x00},//0x19,//0x66

    {0x96, 0x00},
    {0x9a, 0x80},
    {0xb0, 0x84},
    {0xb1, 0x0c},
    {0xb2, 0x0e},

    {0xb3, 0x82},//80
    {0xb8, 0x0a},
    {0x43, 0x14},
    {0x44, 0xf0},
    {0x45, 0x34},

    {0x46, 0x58},
    {0x47, 0x28},
    {0x48, 0x3a},
    {0x59, 0x88},
    {0x5a, 0x88},

    {0x5b, 0x44},//90
    {0x5c, 0x67},
    {0x5d, 0x49},
    {0x5e, 0x0e},
    {0x64, 0x04},
    {0x65, 0x20},

    {0x66, 0x05},
    {0x94, 0x04},
    {0x95, 0x08},
    {0x6c, 0x0a},
    {0x6d, 0x55},


    {0x4f, 0x80},
    {0x50, 0x80},
    {0x51, 0x00},
    {0x52, 0x22},
    {0x53, 0x5e},
    {0x54, 0x80},

    //{0x54, 0x40},//110


    {0x09, 0x03},//驱动能力最大

    {0x6e, 0x11},//100
    {0x6f, 0x9f},//0x9e for advance AWB
    {0x55, 0x00},//亮度
    {0x56, 0x40},//对比度 0x40
    {0x57, 0x40},//0x40,  change according to Jim's request
///
//以下部分代码由开源电子网网友:duanzhang512 提出
//添加此部分代码将可以获得更好的成像效果,但是最下面一行会有蓝色的抖动.
//如不想要,可以屏蔽此部分代码.然后将:OV7670_Window_Set(12,176,240,320);
//改为:OV7670_Window_Set(12,174,240,320);,即可去掉最下一行的蓝色抖动
//  {0x6a, 0x40},
//  {0x01, 0x40},
//  {0x02, 0x40},
//  {0x13, 0xe7},
//  {0x15, 0x00},
//
//
//  {0x58, 0x9e},
//
//  {0x41, 0x08},
//  {0x3f, 0x00},
//  {0x75, 0x05},
//  {0x76, 0xe1},
//  {0x4c, 0x00},
//  {0x77, 0x01},
//  {0x3d, 0xc2},
//  {0x4b, 0x09},
//  {0xc9, 0x60},
//  {0x41, 0x38},
//
//  {0x34, 0x11},
//  {0x3b, 0x02},

//  {0xa4, 0x89},
//  {0x96, 0x00},
//  {0x97, 0x30},
//  {0x98, 0x20},
//  {0x99, 0x30},
//  {0x9a, 0x84},
//  {0x9b, 0x29},
//  {0x9c, 0x03},
//  {0x9d, 0x4c},
//  {0x9e, 0x3f},
//  {0x78, 0x04},
//
//  {0x79, 0x01},
//  {0xc8, 0xf0},
//  {0x79, 0x0f},
//  {0xc8, 0x00},
//  {0x79, 0x10},
//  {0xc8, 0x7e},
//  {0x79, 0x0a},
//  {0xc8, 0x80},
//  {0x79, 0x0b},
//  {0xc8, 0x01},
//  {0x79, 0x0c},
//  {0xc8, 0x0f},
//  {0x79, 0x0d},
//  {0xc8, 0x20},
//  {0x79, 0x09},
//  {0xc8, 0x80},
//  {0x79, 0x02},
//  {0xc8, 0xc0},
//  {0x79, 0x03},
//  {0xc8, 0x40},
//  {0x79, 0x05},
//  {0xc8, 0x30},
//  {0x79, 0x26},
//  {0x09, 0x00},
///
};
#endif /* COMLIB_OV7670_OV7670_OV7670_CFG_H_ */
  • main.c
/* Global define */
#include "ch32v30x.h"
#include "ch32v30x_gpio.h"
#include "ch32v30x_rcc.h"
#include "Delay.h"
#include "OLED1306.h"
#include "OV7670.h"
/* Global Variable */


/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{

    Delay_Init();
    OLED1306_Init();
    OLED1306_ShowString(1, 1, "Hello World!");
    OV7670_Init();

    while(1)
    {

    }
}

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值