一下是我的代码,总感觉没有问题但是就是无法读取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)
{
}
}