⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ov7670.c

📁 OV7670模组带转接板资料
💻 C
字号:
/*******************************************************************************
*  Copyright (C) 2012 All Rights Reserved
*		
* 软件作者:	骑飞家族
* 版权所有: 骑飞电子	
* 创建日期:	2010年6月10日 
* 软件历史:	2010年11月2日修改
			2012年09月10日修改
* Version:  3.0 
* Demo 淘宝地址:http://qifeidz.taobao.com
**********************************************************************************************************************************************

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

#include "OV7670.h"
#include "delay.h"
#include "stm32f10x_lib.h"

// GND         PIN1
// HREF  PC8   PIN2  PC8
// VSYNC       PIN3	 PC11
// PWDN  GND   PIN4
// PCLK  PC9   PIN5 没有用到  PC(
// AVDD  2.8V  PIN6
// DVDD  2.8V  PIN7
// SIOD  PA6   PIN8	 
// XCLK1 PA8   PIN9
// SIOC  PA7   PIN10
// D0    PC0   PIN11
// D1    PC1   PIN12
// D2    PC2   PIN13
// D3    PC3   PIN14
// GND         PIN15
// D4    PC4   PIN16
// D5    PC5   PIN17
// D6    PC6   PIN18
// D7    PC7   PIN19
// RST   GND   PIN20

//extern const char change_reg[CHANGE_REG_NUM][2];
////////////////////////////
//功能:提供7670时钟
//返回:无

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);
    RCC_MCOConfig(RCC_MCO_HSE  );//hsi
}
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);
}
void OV7670_GPIO_Init(void)
{
  
  GPIO_InitTypeDef GPIO_InitStructure;
   /* Enable GPIOC  clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  GPIO_InitStructure.GPIO_Pin =  0X0BFF;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//GPIO_Mode_AF_OD  GPIO_Mode_AF_PP GPIO_Mode_IPU	GPIO_Mode_IN_FLOATING   
  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void OV7670_GPIO_CONTRL_CONFIG(void)
{
  
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = LCD_HREF_BIT|LCD_VSYNC_BIT|LCD_PCLK_BIT;
    //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    RCC_MCOConfig(RCC_MCO_HSE  );//hsi
}
////////////////////////////
//功能:写OV7670寄存器
//返回:1-成功	0-失败
unsigned char wrOV7670Reg(unsigned char regID, unsigned char regDat)
{
	startSCCB();
	if(0==SCCBwriteByte(0x42))
	{
		stopSCCB();
		return(0);
	}
	delay_us(100);
  	if(0==SCCBwriteByte(regID))
	{
		stopSCCB();
		return(0);
	}
	delay_us(100);
  	if(0==SCCBwriteByte(regDat))
	{
		stopSCCB();
		return(0);
	}
  	stopSCCB();
	
  	return(1);
}
////////////////////////////
//功能:读OV7670寄存器
//返回:1-成功	0-失败
unsigned char rdOV7670Reg(unsigned char regID, unsigned char *regDat)
{
	//通过写操作设置寄存器地址
	startSCCB();
	if(0==SCCBwriteByte(0x42))
	{
		stopSCCB();
		return(0);
	}
	delay_us(100);
  	if(0==SCCBwriteByte(regID))
	{
		stopSCCB();
		return(0);
	}
	stopSCCB();
	
	delay_us(100);
	
	//设置寄存器地址后,才是读
	startSCCB();
	if(0==SCCBwriteByte(0x43))
	{
		stopSCCB();
		return(0);
	}
	delay_us(100);
  	*regDat=SCCBreadByte();
  	noAck();
  	stopSCCB();
  	return(1);
}


//(140,16,640,480) is good for VGA
//(272,16,320,240) is good for QVGA
/* config_OV7670_window */
void OV7670_config_window(unsigned int startx,unsigned int starty,unsigned int width, unsigned int height)
{
	unsigned int endx;
	unsigned int endy;// "v*2"必须
	unsigned char temp_reg1, temp_reg2;
	unsigned char temp=0;
	
	endx=(startx+width);
	endy=(starty+height+height);// "v*2"必须
        rdOV7670Reg(0x03, &temp_reg1 );
	temp_reg1 &= 0xf0;
	rdOV7670Reg(0x32, &temp_reg2 );
	temp_reg2 &= 0xc0;
	
	// Horizontal
	temp = temp_reg2|((endx&0x7)<<3)|(startx&0x7);
	wrOV7670Reg(0x32, temp );
	temp = (startx&0x7F8)>>3;
	wrOV7670Reg(0x17, temp );
	temp = (endx&0x7F8)>>3;
	wrOV7670Reg(0x18, temp );
	
	// Vertical
	temp =temp_reg1|((endy&0x3)<<2)|(starty&0x3);
	wrOV7670Reg(0x03, temp );
	temp = starty>>2;
	wrOV7670Reg(0x19, temp );
	temp = endy>>2;
	wrOV7670Reg(0x1A, temp );
}

set_OV7670reg(void)
{
	//wrOV7670Reg(0x8c, 0x00);  //写RGB444寄存器  RGB444非使能  xRGB
	wrOV7670Reg(0x3a, 0x04);  //TSLB  行缓冲器测试选项  使用通用UV输出  输出顺序 YUYV   当分辨率改变时传感器不会自动设置窗口,后端处理器能够自动调整窗口
	wrOV7670Reg(0x40, 0xd0);  //COM15 数据输出范围(00-ff) RGB565
	wrOV7670Reg(0x8c, 0x00);  
	wrOV7670Reg(0x12, 0x14);  //COM7 SCCB不复位 输出格式QVGA  RGB输出
	wrOV7670Reg(0x32, 0x80);  //HREF控制  HREF沿距离数据输出的偏移为10 HREF(行频率)开始的低三位及结束的低三位都为0
	wrOV7670Reg(0x17, 0x16);  //行频开始的高8位	wrOV7670Reg(0x18, 0x04);  //行频结束的高8位
	wrOV7670Reg(0x19, 0x02);  //场频开始的高8位
	wrOV7670Reg(0x1a, 0x7b);  //场频结束的高8位
	wrOV7670Reg(0x03, 0x06);  //场频开始的低2位及结束的低两位
	wrOV7670Reg(0x0c, 0x04);  //COM3 输出数据高位与地位不交换 在省电模式下输出时钟为3态 缩放禁止 数据控制字使能
	wrOV7670Reg(0x3e, 0x00);  // 复位值 正常PCLK(即不分频)  缩放参数不能手动调节 
	wrOV7670Reg(0x70, 0x3a);  //复位值  无测试图案输出  水平缩放系数为0x3a
	wrOV7670Reg(0x71, 0x35);  // 复位值  .............  垂直缩放系数为0x35
	wrOV7670Reg(0x72, 0x11);  // 复位值 DCW控制 垂直均值舍去  垂直 down samping 舍去 垂直down samping率为2采一 水平同垂直
	wrOV7670Reg(0x73, 0x00);  //复位值   旁路dsp缩放时钟使能  dsp缩放时钟分频控制无效
	wrOV7670Reg(0xa2, 0x00);  //缩放输出延时
	wrOV7670Reg(0x11, 0xff);  //直接使用外部时钟(没有预分频)内部时钟分频 内部时钟=输入时钟/位(【5:0】+1) 为64KHZ
	//wrOV7670Reg(0x15 , 0x31);//复位值 HREF不转变为HSYNC PCLK 连续输出 PLK不反相 HREF不反相 VSYC在PCLK下降沿改变VSNC 及HSYNC负有效
	wrOV7670Reg(0x7a, 0x20);   //SLOP 伽玛曲线最高段斜率 斜率(SLOP【7:0】)=(0x100-GAM15【7:0】)*4/3
	wrOV7670Reg(0x7b, 0x1c);   //伽玛曲线1节输入结束点0x04输出值
	wrOV7670Reg(0x7c, 0x28); 	//.......2............0x08......
	wrOV7670Reg(0x7d, 0x3c);	//.......3...........0x10.....
	wrOV7670Reg(0x7e, 0x55); 	//.......4...........0x20......
	wrOV7670Reg(0x7f, 0x68);   //.......5...........0x28......
	wrOV7670Reg(0x80, 0x76);	//.......6...........0x30......
	wrOV7670Reg(0x81, 0x80);   //.......7...........0x38......
	wrOV7670Reg(0x82, 0x88);   //.......8...........0x40......
	wrOV7670Reg(0x83, 0x8f);   //.......9...........0x48......
	wrOV7670Reg(0x84, 0x96);   //.......10...........0x50......
	wrOV7670Reg(0x85, 0xa3);	//.......11...........0x60......
	wrOV7670Reg(0x86, 0xaf);	//.......12...........0x70......
	wrOV7670Reg(0x87, 0xc4); 	//.......13...........0x90......
	wrOV7670Reg(0x88, 0xd7);	//.......14...........0xb0......
	wrOV7670Reg(0x89, 0xe8);  //伽玛曲线15节输入结束点0xd0输出值
	 
	wrOV7670Reg(0x32,0xb6);	   //HREF控制  HREF沿距离数据输出的偏移 【7:6】   HREF(行频率)开始的低三位及结束的低三位都为110
																	  
	wrOV7670Reg(0x13, 0xff);  //使能AGC/AEC算法 AEC不限制步长 条纹滤波器开 AGC,AWB,AEC使能
	wrOV7670Reg(0x00, 0x00);  //AGC(自动增益控制)	由0x00【7:0】及0x03寄存器【7:6】(高两位)
	wrOV7670Reg(0x10, 0x00);  //AEC (曝光值)由寄存器 07的【5:0】表示AEC的[15:10] 寄存器10的【7:0】表示AEC【9:2】由寄存器0x04的【1:0】表示AEC的低两位
	wrOV7670Reg(0x0d, 0x00);  //AEC的窗口选择      全窗口
	wrOV7670Reg(0x14, 0x4e);  //最大AGC值     32*AGC    不是固定的AGC/AEC
	wrOV7670Reg(0xa5, 0x05);   //50Hz条纹滤波器步长限制
	wrOV7670Reg(0xab, 0x07);   //60Hz滤波器步长限制
	wrOV7670Reg(0x24, 0x75);   //AGC/AEC稳定运行区域(上限)
	wrOV7670Reg(0x25, 0x63);   //AGC/AEC稳定运行区域(下限)
	wrOV7670Reg(0x26, 0xA5);   //AGC/AEC快速稳定运行  【7:4】上限 【3:0】下限
	wrOV7670Reg(0x9f, 0x78);   //基于直方图的AGC/AEC控制1
	wrOV7670Reg(0xa0, 0x68);   //基于直方图的AGC/AEC控制2
//	wrOV7670Reg(0xa1, 0x03);//0x0b,
	wrOV7670Reg(0xa6, 0xdf);   ////基于直方图的AGC/AEC控制3
	wrOV7670Reg(0xa7, 0xdf);   //基于直方图的AGC/AEC控制4
	wrOV7670Reg(0xa8, 0xf0);   //基于直方图的AGC/AEC控制5
	wrOV7670Reg(0xa9, 0x90);   //基于直方图的AGC/AEC控制6
	wrOV7670Reg(0xaa, 0x94);   //AEC公式选择    基于直方图的AEC算法
	//wrOV7670Reg(0x13, 0xe5); 
	wrOV7670Reg(0x0e, 0x61);   //通用控制5 保留
	wrOV7670Reg(0x0f, 0x43);   //在光学黒行输出时禁止HREF  当格式变化时复位所有时序
	wrOV7670Reg(0x16, 0x02);   //RSVD 保留
	wrOV7670Reg(0x1e, 0x37);   // 水平翻转不使能  竖直翻转不使能 (black sun 使能 )
	wrOV7670Reg(0x21, 0x02);   //保留
	wrOV7670Reg(0x22, 0x91);   //保留
	wrOV7670Reg(0x29, 0x07);   //保留
	wrOV7670Reg(0x33, 0x0b);   //感光阵列电流控制
	wrOV7670Reg(0x35, 0x0b);   //保留
	wrOV7670Reg(0x37, 0x3f);   //ADC控制
	wrOV7670Reg(0x38, 0x01);   //ADC和模拟共模控制
	wrOV7670Reg(0x39, 0x00);   //ADC偏移控制
	wrOV7670Reg(0x3c, 0x78);   //在VSYNC为底时没有HREF
	wrOV7670Reg(0x4d, 0x40);   //保留
	wrOV7670Reg(0x4e, 0x20);   //保留
	wrOV7670Reg(0x69, 0x00);   //Gr,Gb,R,B通道的固定增益值为1*AEC
	wrOV7670Reg(0x6b, 0x4a);   // 输入时钟*4  校准器控制 使能内部校准器
	wrOV7670Reg(0x74, 0x19);   //选择VREF【7:6】(即0x03寄存器)为控制数字增益
	wrOV7670Reg(0x8d, 0x4f);  // 保留
	wrOV7670Reg(0x8e, 0x00);   // 保留
	wrOV7670Reg(0x8f, 0x00);   //保留
	wrOV7670Reg(0x90, 0x00);   //保留
	wrOV7670Reg(0x91, 0x00);	//保留
	wrOV7670Reg(0x92, 0x00);	//空行低8位
	wrOV7670Reg(0x96, 0x00);	//保留
	wrOV7670Reg(0x9a, 0x80);	//保留
	wrOV7670Reg(0xb0, 0x84);	//保留
	wrOV7670Reg(0xb1, 0x0c);	//自动黑电平校准禁使能
	wrOV7670Reg(0xb2, 0x0e);	//保留
	wrOV7670Reg(0xb3, 0x82);	//自动黑电平矫正目标值
	wrOV7670Reg(0xb8, 0x0a);	 //保留
	wrOV7670Reg(0x43, 0x14);	//保留
	wrOV7670Reg(0x44, 0xf0);	 //保留
	wrOV7670Reg(0x45, 0x34);
	wrOV7670Reg(0x46, 0x58);
	wrOV7670Reg(0x47, 0x28);
	wrOV7670Reg(0x48, 0x3a);	 //保留
	
	wrOV7670Reg(0x59, 0x88);	 //AWB控制(59-61 )
	wrOV7670Reg(0x5a, 0x88);
	wrOV7670Reg(0x5b, 0x44);
	wrOV7670Reg(0x5c, 0x67);
	wrOV7670Reg(0x5d, 0x49);
	wrOV7670Reg(0x5e, 0x0e);
	
	wrOV7670Reg(0x64, 0x04);	//镜头补偿选项3  G通道补偿系数
	wrOV7670Reg(0x65, 0x20);	  //镜头补偿选项4 避免补偿半径
	wrOV7670Reg(0x66, 0x05);	 //RGB镜头补偿系数由寄存器0x64(G)	)0x94(R)0x95(B)
	wrOV7670Reg(0x94, 0x04);	 //R通道补偿系数
	wrOV7670Reg(0x95, 0x08);	 //B通道补偿系数

	wrOV7670Reg(0x6c, 0x0a);	 //	AWB控制3
	wrOV7670Reg(0x6d, 0x55);	 //AWB控制2
	wrOV7670Reg(0x6e, 0x11);	 //AWB控制1
	wrOV7670Reg(0x6f, 0x9f); 	//AWB控制0

	wrOV7670Reg(0x6a, 0x40);	//G通道AWB增益
	wrOV7670Reg(0x01, 0x40);	//B通道AWB增益
	wrOV7670Reg(0x02, 0x40);   //r通道AWB增益
	
	//wrOV7670Reg(0x13, 0xe7);
	wrOV7670Reg(0x15, 0x00);  // /复位值 HREF不转变为HSYNC PCLK 连续输出 PLK不反相 HREF不反相 VSYC在PCLK下降沿改变VSNC 及HSYNC正有效  
	wrOV7670Reg(0x4f, 0x80);   //色彩矩阵系数1
	wrOV7670Reg(0x50, 0x80);	//色彩矩阵系数2
	wrOV7670Reg(0x51, 0x00);  //色彩矩阵系数3
	wrOV7670Reg(0x52, 0x22);   //色彩矩阵系数4
	wrOV7670Reg(0x53, 0x5e);	//色彩矩阵系数5
	wrOV7670Reg(0x54, 0x80);	//色彩矩阵系数6
	wrOV7670Reg(0x58, 0x9e);	//色彩矩阵系数5-0  	对比度中心使能  寄存器0x57自动更新

	wrOV7670Reg(0x41, 0x08);	//针对YUV边缘增强阀值自动调整禁止 AWB(白平衡)增益使能
	wrOV7670Reg(0x3f, 0x00);	//边缘增强调整【4:0】边缘增强系数
	wrOV7670Reg(0x75, 0x05);	//边缘增强下限【4:0】
	wrOV7670Reg(0x76, 0xe1);	//黑点纠正使能 白点纠正使能  边缘增强上限【4:0】

	wrOV7670Reg(0x4c, 0x00);	//噪声抑制强度
	wrOV7670Reg(0x77, 0x01);	//噪声去除偏移
	
	wrOV7670Reg(0x3d, 0xc1);   //Camma使能  uv饱和度自动调整,结果存入寄存器0xc9的【3:】uv不交换位置
	wrOV7670Reg(0x4b, 0x09);	//uv平均使能
	wrOV7670Reg(0xc9, 0x60);	//饱和度控制【7:4】饱和度控制最小值【3:0】饱和度控制结果
	//wrOV7670Reg(0x41, 0x38);	
	wrOV7670Reg(0x56, 0x40);	//对比度控制		 复位值
	wrOV7670Reg(0x34, 0x11);	//感光阵列参考电压控制	  复位值
	wrOV7670Reg(0x3b, 0x02);	//禁止夜晚模式  失能50/60Hz自动侦测  选择BD60ST作为条纹滤波值 曝光时间可以小于条纹滤波器限制
	wrOV7670Reg(0xa4, 0x89);	 //帧率减半  在4*增益插入空行
	
	wrOV7670Reg(0x96, 0x00);	//保留
	wrOV7670Reg(0x97, 0x30);
	wrOV7670Reg(0x98, 0x20);
	wrOV7670Reg(0x99, 0x30);
	wrOV7670Reg(0x9a, 0x84);
	wrOV7670Reg(0x9b, 0x29);
	wrOV7670Reg(0x9c, 0x03); //保留
	wrOV7670Reg(0x9d, 0x4c); //50hz条纹滤波器的值
	wrOV7670Reg(0x9e, 0x3f); //60hz条纹滤波器的值	

	wrOV7670Reg(0x09, 0x00); //输出驱动能力1*
	wrOV7670Reg(0x3b, 0xc2); //失能夜晚模式1/4普通帧率 失能50/60Hz自动侦测  选择BD60ST作为条纹滤波值 曝光时间可以小于条纹滤波器限制

}/* OV7670_init() */
//返回1成功,返回0失败
unsigned char OV7670_init(void)
{
	unsigned char temp;	
//	unsigned int i=0;

	OV7670_GPIO_Init();
	OV7670_GPIO_CONTRL_CONFIG();
	SCCB_GPIO_Config(); // io init..

    CLK_init_ON();
	temp=0x80;
	if(0==wrOV7670Reg(0x12, temp)) //Reset SCCB
	{
        return 0 ;
	}
	delay_ms(100);
  	set_OV7670reg();

	OV7670_config_window(272,12,320,240);// set 240*320
	return 0x01; //ok			  
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -