标题:
STM32F407 OV7670摄像头例程
[打印本页]
作者:
砚子儿
时间:
2017-8-6 21:16
标题:
STM32F407 OV7670摄像头例程
1、该例程为OV7670摄像头例程。
2、使用说明
(1)工程文件路径:SY-STM32F407 V2程序\SY-STM32F407 V2例程:OV7670摄像头例程\Project\Project.uvproj。
(2)请使用MDK 4.0以上版本打开,MDK版本过低会导致无法识别工程。
(3)下载调试工具为JLINK。
(4)请将串口线(直连串口线)插在板子COM1口上,并打开超级终端或串口助手,配置波特率115200,8位,一个停止位,无校验位。
(5)HEX文件下载到板子后,使用超级终端或串口调试助手可以看到调试信息。
(6)插上TFT模块,插上摄像头模块,TFT显示摄像头采集图像,表明例程运行正确。
3、注意事项
请务必在下载、调试、运行过程中,保持板子上电、JLINK连接并插在电脑上。
全部资料下载地址:
STM32F407 OV7670摄像头例程.rar
(470.73 KB, 下载次数: 480)
2017-8-6 21:16 上传
点击文件名下载附件
下载积分: 黑币 -5
stm32部分源码预览:
#include "ov7670.h"
#include "delay.h"
#include "lcd.h"
void Cam_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DCMI_InitTypeDef DCMI_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);//DCMI
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);//DMA2
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE);//使能DCMI的GPIO时钟
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_MCO);//MCO1:PA8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_MCO2Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_3);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PE5:PWRDOWN
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_ResetBits(GPIOE, GPIO_Pin_5);//power on
GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);//DCMI_HSYNC
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_PIXCLK
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_D5
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);//DCMI_VSYNC
GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_DCMI);//DCMI_D6
GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_D7
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI);//DCMI_D0
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI);//DCMI_D1
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_DCMI);//DCMI_D2
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_DCMI);//DCMI_D3
GPIO_PinAFConfig(GPIOE, GPIO_PinSource4, GPIO_AF_DCMI);//DCMI_D4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Falling;
DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;
DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_High;
DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
DCMI_Init(&DCMI_InitStructure);
DMA_DeInit(DMA2_Stream1);
DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = FSMC_LCD_ADDRESS;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);
}
u8 OV7670_Init(void)
{
u8 i;
Cam_Init();
SCCB_Init();
OV_Reset();
delay_ms(5);
LCD_String(20,50,"Camera ID:",RED);
LCD_Num(180,50,OV_ReadID(),3,WHITE);//ov7670 ID为0x73
for(i=0;i<OV7670_REG_NUM;i++)
{
if(OV_WriteReg(OV7670_reg[i][0],OV7670_reg[i][1]))return 1;
}
return 0;
}
void Cam_Start(void)
{
LCD_WriteReg(0x03,0x1018);
LCD_Cursor(0,319);
DMA_Cmd(DMA2_Stream1, ENABLE);
DCMI_Cmd(ENABLE);
DCMI_CaptureCmd(ENABLE);
LCD_REG=0x22;
}
void OV7670_HW(u16 hstart,u16 vstart,u16 hstop,u16 vstop)
{
u8 v;
OV_WriteReg(0x17,(hstart>>3)&0xff);//HSTART
OV_WriteReg(0x18,(hstop>>3)&0xff);//HSTOP
OV_ReadReg(0x32,&v);
v=(v&0xc0)|((hstop&0x7)<<3)|(hstart&0x7);
OV_WriteReg(0x32,v);//HREF
OV_WriteReg(0x19,(vstart>>2)&0xff);//VSTART 开始高8位
OV_WriteReg(0x1a,(vstop>>2)&0xff);//VSTOP 结束高8位
OV_ReadReg(0x03,&v);
v=(v&0xf0)|((vstop&0x3)<<2)|(vstart&0x3);
OV_WriteReg(0x03,v);//VREF
OV_WriteReg(0x11,0x00);
}
/////////////////////////////////////
void SCCB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; //SCCB_SIC:PB10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //SCCB_SID:PB11
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SCCB_SID_OUT(void)//设置SCCB_SID为输出
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SCCB_SID_IN(void)//设置SCCB_SID为输入
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SCCB_Start(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);
}
void SCCB_Stop(void)
{
SCCB_SID_L();
delay_us(50);
SCCB_SIC_H();
delay_us(50);
SCCB_SID_H();
delay_us(50);
}
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);
}
u8 SCCB_Write(u8 m_data)
{
u8 j,tem;
for(j=0;j<8;j++) //循环8次发送数据
{
if((m_data<<j)&0x80)SCCB_SID_H();
else SCCB_SID_L();
delay_us(50);
SCCB_SIC_H();
delay_us(50);
SCCB_SIC_L();
delay_us(50);
}
delay_us(10);
SCCB_DATA_IN;
delay_us(50);
SCCB_SIC_H();
delay_us(10);
if(SCCB_SID_STATE)tem=0;//SDA=1发送失败
else tem=1;//SDA=0发送成功,返回1
SCCB_SIC_L();
delay_us(50);
SCCB_DATA_OUT;
return tem;
}
u8 SCCB_Read(void)
{
u8 read,j;
read=0x00;
SCCB_DATA_IN;
delay_us(50);
for(j=8;j>0;j--) //循环8次接收数据
{
delay_us(50);
SCCB_SIC_H();
delay_us(50);
read=read<<1;
if(SCCB_SID_STATE)read=read+1;
SCCB_SIC_L();
delay_us(50);
}
SCCB_DATA_OUT;
return read;
}
//写OV7670寄存器
u8 OV_WriteReg(u8 regID, u8 regDat)
{
SCCB_Start();//发送SCCB 总线开始传输命令
if(SCCB_Write(0x42)==0)//写地址
{
SCCB_Stop();//发送SCCB 总线停止传输命令
return 1;//错误返回
}
delay_us(10);
if(SCCB_Write(regID)==0)//积存器ID
{
SCCB_Stop();//发送SCCB 总线停止传输命令
return 2;//错误返回
}
delay_us(10);
if(SCCB_Write(regDat)==0)//写数据到积存器
{
SCCB_Stop();//发送SCCB 总线停止传输命令
return 3;//错误返回
}
SCCB_Stop();//发送SCCB 总线停止传输命令
return 0;//成功返回
}
//读OV7660寄存器
u8 OV_ReadReg(u8 regID, u8 *regDat)
{
//通过写操作设置寄存器地址
SCCB_Start();
if(SCCB_Write(0x42)==0)//写地址
{
SCCB_Stop();//发送SCCB 总线停止传输命令
return 1;//错误返回
}
delay_us(10);
if(SCCB_Write(regID)==0)//积存器ID
{
SCCB_Stop();//发送SCCB 总线停止传输命令
return 2;//错误返回
}
SCCB_Stop();//发送SCCB 总线停止传输命令
delay_us(10);
//设置寄存器地址后,才是读
SCCB_Start();
if(SCCB_Write(0x43)==0)//读地址
{
SCCB_Stop();//发送SCCB 总线停止传输命令
return 3;//错误返回
}
delay_us(10);
*regDat=SCCB_Read();//返回读到的值
noAck();//发送NACK命令
SCCB_Stop();//发送SCCB 总线停止传输命令
return 0;//成功返回
}
void OV_Reset(void)
{
OV_WriteReg(0x12,0x80);
}
u8 OV_ReadID(void)
{
u8 temp;
OV_ReadReg(0x0b,&temp);
return temp;
}
复制代码
作者:
yhj416606438
时间:
2018-2-14 08:33
谢谢分享!!!!!
作者:
梦园心田
时间:
2018-10-3 20:33
可以用吗
作者:
时间:
2018-10-6 15:54
感谢分享
作者:
马克老兄
时间:
2018-10-7 16:29
感谢楼主分享例程
作者:
caonimaaaaa
时间:
2018-11-19 14:55
啊!非常感谢
作者:
李秀莲
时间:
2019-3-18 17:06
为什么按照例程烧写进板子后,LCD没有图像显示
作者:
zh21107066
时间:
2019-4-13 09:14
多谢楼主,下来试试
作者:
leemor
时间:
2019-5-6 18:44
谢谢分享 正在学习中,很有用
作者:
310139033
时间:
2019-7-13 21:22
感谢楼主分享,真的需要
作者:
木子一
时间:
2019-7-29 17:51
谢谢大佬
作者:
dan2451093708
时间:
2020-2-4 17:53
你好,请问此例程是运行在什么硬件环境的呢?比如正点原子探索者开发板吗?是使用的正点原子的OV7670摄像头(带FIFO)吗?显示屏用的几寸屏呢?
作者:
aaaaaa。
时间:
2020-3-2 09:39
楼主,你这个程序的功能是什么
作者:
xxx224
时间:
2020-8-13 16:43
有没有道友调试成功的,为啥我lcd显示不出来
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1