本摄像头ov7670驱动程序已经通过本人的验证可以正常运行,不同的STM32开发板只需要修改引脚即可使用,所有内容打包下载:
stm32驱动摄像头ov7670源程序.rar
下面是部分源码预览:
- /*
- wangguanfu@163.com
- 未经过本人许可禁止任何商业用途
- */
- #include "Sensor.h"
- #include "delay.h"
- #include "Sensor_config.h"
- #include "stm32f10x.h"
- extern const char OV7670_reg[OV7670_REG_NUM][2];
- ////////////////////////////
- //功能:提供时钟
- //guanfu_wang
- /*
- void XCLK_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_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- RCC_MCOConfig(RCC_MCO_HSE );//hsi
- }
- */
- /////////////////////////////
- //VSYNC GPIO INIT
- //guanfu_wang
- void Sensor_GPIO_Init(void)//
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- // Enable GPIOC clock
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
- GPIO_InitStructure.GPIO_Pin = Sensor_VSYNC_BIT;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;////上拉
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- //////////////////////////////////////////////////
- ////函数功能:中断配制
- //guanfu_wang
- void Sensor_Interrupts_Config(void)//VSYNC 中断
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- /* Configure one bit for preemption priority */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
- /* Configure one bit for preemption priority */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
- /* Enable the EXTI9_5 Interrupt */
- NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- ////////////////////////////////////////////////////////////////////////
- void Sensor_EXTI_Config(void)//VSYNC 中断
- {
- EXTI_InitTypeDef EXTI_InitStructure;
- GPIO_EXTILineConfig(GPIO_PORT_SOURCE_VSYNC_CMOS, GPIO_PIN_SOURCE_VSYNC_CMOS);
- EXTI_InitStructure.EXTI_Line = EXTI_LINE_VSYNC_CMOS;
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure);
- EXTI_GenerateSWInterrupt(EXTI_LINE_VSYNC_CMOS);
- }
- ///////////////////////////////////////////////////////////////////////////
- //功能:写OV7660寄存器
- //返回:1-成功 0-失败
- //guanfu_wang
- unsigned char wr_Sensor_Reg(unsigned char regID, unsigned char regDat)
- {
- startSCCB();//发送SCCB 总线开始传输命令
- if(0==SCCBwriteByte(0x42))//写地址
- {
- stopSCCB();//发送SCCB 总线停止传输命令
- return(0);//错误返回
- }
- delay_us(20);
- if(0==SCCBwriteByte(regID))//积存器ID
- {
- stopSCCB();//发送SCCB 总线停止传输命令
- return(0);//错误返回
- }
- delay_us(20);
- if(0==SCCBwriteByte(regDat))//写数据到积存器
- {
- stopSCCB();//发送SCCB 总线停止传输命令
- return(0);//错误返回
- }
- stopSCCB();//发送SCCB 总线停止传输命令
- return(1);//成功返回
- }
- ////////////////////////////
- //功能:读OV7660寄存器
- //返回:1-成功 0-失败
- //guanfu_wang
- unsigned char rd_Sensor_Reg(unsigned char regID, unsigned char *regDat)
- {
- //通过写操作设置寄存器地址
- startSCCB();
- if(0==SCCBwriteByte(0x42))//写地址
- {
- stopSCCB();//发送SCCB 总线停止传输命令
- return(0);//错误返回
- }
- delay_us(20);
- if(0==SCCBwriteByte(regID))//积存器ID
- {
- stopSCCB();//发送SCCB 总线停止传输命令
- return(0);//错误返回
- }
- stopSCCB();//发送SCCB 总线停止传输命令
- delay_us(20);
- //设置寄存器地址后,才是读
- startSCCB();
- if(0==SCCBwriteByte(0x43))//读地址
- {
- stopSCCB();//发送SCCB 总线停止传输命令
- return(0);//错误返回
- }
- delay_us(20);
- *regDat=SCCBreadByte();//返回读到的值
- noAck();//发送NACK命令
- stopSCCB();//发送SCCB 总线停止传输命令
- return(1);//成功返回
- }
- /* Sensor_init() */
- //返回1成功,返回0失败
- //guanfu_wang
- unsigned char Sensor_init(void)
- {
- unsigned char temp;
- unsigned int i=0;
- // XCLK_init_ON();//开启MCO功能 提供时钟给CMOS传感器
- //uchar ovidm***=0,ovidl***=0;
- Sensor_GPIO_Init();
- SCCB_GPIO_Config();//io init..
- temp=0x80;
- if(0==wr_Sensor_Reg(0x12, temp)) //Reset SCCB
- {
- return 0 ;//错误返回
- }
- Delay(1);
- if(0==rd_Sensor_Reg(0x0b, &temp))//读ID
- {
- return 0 ;//错误返回
- }
- if(temp==0x73)//OV7670
- {
- for(i=0;i {
- if( 0==wr_Sensor_Reg(OV7670_reg[0],OV7670_reg[1]))
- {
- return 0;//错误返回
- }
- }
- Sensor_EXTI_Config();
- Sensor_Interrupts_Config();
- }
- return 0x01; //ok
- }
- ///////////////////
- /*
- wangguanfu@163.com
- 未经过本人许可禁止任何商业用途
- */
- #include "sccb.h"
- #include "delay.h"
- #include "stm32f10x.h"
- /*
- -----------------------------------------------
- 功能: 初始化模拟SCCB接口
- 参数: 无
- 返回值: 无
- -----------------------------------------------
- */
- void SCCB_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /* Enable GPIOC clock */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- GPIO_InitStructure.GPIO_Pin = SCCB_SIC_BIT|SCCB_SID_BIT;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- void SCCB_SID_GPIO_OUTPUT(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /* Enable GPIOC clock */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- GPIO_InitStructure.GPIO_Pin = SCCB_SID_BIT;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- void SCCB_SID_GPIO_INPUT(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /* Enable GPIOC clock */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- GPIO_InitStructure.GPIO_Pin = SCCB_SID_BIT;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉 若无外部上拉电阻 必须内部有上拉
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- /*
- -----------------------------------------------
- 功能: start命令,SCCB的起始信号
- 参数: 无
- 返回值: 无
- -----------------------------------------------
- */
- void startSCCB(void)
- {
- SCCB_SID_H(); //数据线高电平
- delay_us(50);
- SCCB_SIC_H(); //在时钟线高的时候数据线由高至低
- delay_us(50);
- SCCB_SID_L();
- delay_us(50);
- SCCB_SIC_L(); //数据线恢复低电平,单操作函数必要
- delay_us(50);
- }
- /*
- -----------------------------------------------
- 功能: stop命令,SCCB的停止信号
- 参数: 无
- 返回值: 无
- -----------------------------------------------
- */
- void stopSCCB(void)
- {
- SCCB_SID_L();
- delay_us(50);
- SCCB_SIC_H();
- delay_us(50);
- SCCB_SID_H();
- delay_us(50);
- }
- /*
- -----------------------------------------------
- 功能: noAck,用于连续读取中的最后一个结束周期
- 参数: 无
- 返回值: 无
- -----------------------------------------------
- */
- void noAck(void)
- {
- SCCB_SID_H();
- delay_us(50);
- SCCB_SIC_H();
- delay_us(50);
- SCCB_SIC_L();
- delay_us(50);
- SCCB_SID_L();
- delay_us(50);
- }
- /*
- -----------------------------------------------
- 功能: 写入一个字节的数据到SCCB
- 参数: 写入数据
- 返回值: 发送成功返回1,发送失败返回0
- -----------------------------------------------
- */
- unsigned char SCCBwriteByte(unsigned char m_data)
- {
- unsigned char j,tem;
- for(j=0;j<8;j++) //循环8次发送数据
- {
- if((m_data< {
- SCCB_SID_H();
- }
- else
- {
- SCCB_SID_L();
- }
- delay_us(50);
- SCCB_SIC_H();
- delay_us(50);
- SCCB_SIC_L();
- delay_us(2);
- }
- //delay_us(50);
- SCCB_SID_IN;/*设置SDA为输入*/
- delay_us(10);
- SCCB_SIC_H();
- delay_us(80);
- if(SCCB_SID_STATE){tem=0;} //SDA=1发送失败,返回0}
- else {tem=1;} //SDA=0发送成功,返回1
- SCCB_SIC_L();
- delay_us(50);
- SCCB_SID_OUT;/*设置SDA为输出*/
- return (tem);
- }
- /*
- -----------------------------------------------
- 功能: 一个字节数据读取并且返回
- 参数: 无
- 返回值: 读取到的数据
- -----------------------------------------------
- */
- unsigned char SCCBreadByte(void)
- {
- unsigned char read,j;
- read=0x00;
- SCCB_SID_IN;/*设置SDA为输入*/
- delay_us(50);
- for(j=8;j>0;j--) //循环8次接收数据
- {
- //delay_us(100);
- SCCB_SIC_H();
- delay_us(50);
- read=read<<1;
- if(SCCB_SID_STATE)
- {
- read=read+1;
- }
- SCCB_SIC_L();
- delay_us(50);
- }
- SCCB_SID_OUT;/*设置SDA为输出*/
- return(read);
- }
|
0
|
|
|
|