標(biāo)題:
STM32F407 OV7670攝像頭例程
[打印本頁]
作者:
硯子兒
時(shí)間:
2017-8-6 21:16
標(biāo)題:
STM32F407 OV7670攝像頭例程
1、該例程為OV7670攝像頭例程。
2、使用說明
(1)工程文件路徑:SY-STM32F407 V2程序\SY-STM32F407 V2例程:OV7670攝像頭例程\Project\Project.uvproj。
(2)請(qǐng)使用MDK 4.0以上版本打開,MDK版本過低會(huì)導(dǎo)致無法識(shí)別工程。
(3)下載調(diào)試工具為JLINK。
(4)請(qǐng)將串口線(直連串口線)插在板子COM1口上,并打開超級(jí)終端或串口助手,配置波特率115200,8位,一個(gè)停止位,無校驗(yàn)位。
(5)HEX文件下載到板子后,使用超級(jí)終端或串口調(diào)試助手可以看到調(diào)試信息。
(6)插上TFT模塊,插上攝像頭模塊,TFT顯示攝像頭采集圖像,表明例程運(yùn)行正確。
3、注意事項(xiàng)
請(qǐng)務(wù)必在下載、調(diào)試、運(yùn)行過程中,保持板子上電、JLINK連接并插在電腦上。
全部資料下載地址:
STM32F407 OV7670攝像頭例程.rar
(470.73 KB, 下載次數(shù): 480)
2017-8-6 21:16 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
stm32部分源碼預(yù)覽:
#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時(shí)鐘
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 結(jié)束高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)//設(shè)置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)//設(shè)置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(); //數(shù)據(jù)線高電平
delay_us(50);
SCCB_SIC_H(); //在時(shí)鐘線高的時(shí)候數(shù)據(jù)線由高至低
delay_us(50);
SCCB_SID_L();
delay_us(50);
SCCB_SIC_L(); //數(shù)據(jù)線恢復(fù)低電平,單操作函數(shù)必要
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++) //循環(huán)8次發(fā)送數(shù)據(jù)
{
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發(fā)送失敗
else tem=1;//SDA=0發(fā)送成功,返回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--) //循環(huán)8次接收數(shù)據(jù)
{
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();//發(fā)送SCCB 總線開始傳輸命令
if(SCCB_Write(0x42)==0)//寫地址
{
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 1;//錯(cuò)誤返回
}
delay_us(10);
if(SCCB_Write(regID)==0)//積存器ID
{
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 2;//錯(cuò)誤返回
}
delay_us(10);
if(SCCB_Write(regDat)==0)//寫數(shù)據(jù)到積存器
{
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 3;//錯(cuò)誤返回
}
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 0;//成功返回
}
//讀OV7660寄存器
u8 OV_ReadReg(u8 regID, u8 *regDat)
{
//通過寫操作設(shè)置寄存器地址
SCCB_Start();
if(SCCB_Write(0x42)==0)//寫地址
{
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 1;//錯(cuò)誤返回
}
delay_us(10);
if(SCCB_Write(regID)==0)//積存器ID
{
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 2;//錯(cuò)誤返回
}
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
delay_us(10);
//設(shè)置寄存器地址后,才是讀
SCCB_Start();
if(SCCB_Write(0x43)==0)//讀地址
{
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 3;//錯(cuò)誤返回
}
delay_us(10);
*regDat=SCCB_Read();//返回讀到的值
noAck();//發(fā)送NACK命令
SCCB_Stop();//發(fā)送SCCB 總線停止傳輸命令
return 0;//成功返回
}
void OV_Reset(void)
{
OV_WriteReg(0x12,0x80);
}
u8 OV_ReadID(void)
{
u8 temp;
OV_ReadReg(0x0b,&temp);
return temp;
}
復(fù)制代碼
作者:
yhj416606438
時(shí)間:
2018-2-14 08:33
謝謝分享。。。!
作者:
夢(mèng)園心田
時(shí)間:
2018-10-3 20:33
可以用嗎
作者:
時(shí)間:
2018-10-6 15:54
感謝分享
作者:
馬克老兄
時(shí)間:
2018-10-7 16:29
感謝樓主分享例程
作者:
caonimaaaaa
時(shí)間:
2018-11-19 14:55
啊!非常感謝
作者:
李秀蓮
時(shí)間:
2019-3-18 17:06
為什么按照例程燒寫進(jìn)板子后,LCD沒有圖像顯示
作者:
zh21107066
時(shí)間:
2019-4-13 09:14
多謝樓主,下來試試
作者:
leemor
時(shí)間:
2019-5-6 18:44
謝謝分享 正在學(xué)習(xí)中,很有用
作者:
310139033
時(shí)間:
2019-7-13 21:22
感謝樓主分享,真的需要
作者:
木子一
時(shí)間:
2019-7-29 17:51
謝謝大佬
作者:
dan2451093708
時(shí)間:
2020-2-4 17:53
你好,請(qǐng)問此例程是運(yùn)行在什么硬件環(huán)境的呢?比如正點(diǎn)原子探索者開發(fā)板嗎?是使用的正點(diǎn)原子的OV7670攝像頭(帶FIFO)嗎?顯示屏用的幾寸屏呢?
作者:
aaaaaa。
時(shí)間:
2020-3-2 09:39
樓主,你這個(gè)程序的功能是什么
作者:
xxx224
時(shí)間:
2020-8-13 16:43
有沒有道友調(diào)試成功的,為啥我lcd顯示不出來
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1