今天學(xué)習(xí)攝像頭模塊,使用該模塊進行拍攝,照相等功能進行對stm32 控制板的結(jié)合,了解他的原理以及應(yīng)用。
主角: ov7670攝像頭模塊。(大概了解一下產(chǎn)品背景)
?OV7670 是 OV( OmniVision)公司生產(chǎn)的一顆 1/6 寸的 CMOS VGA 圖像傳 感器。該傳感器體積小、工作電壓低,提供單片 VGA 攝像頭和影像處理器的所 有功能。通過 SCCB 總線控制,可以輸出整幀、子采樣、取窗口等方式的各種分 辨率 8 位影像數(shù)據(jù)。該產(chǎn)品 VGA 圖像最高達到 30 幀/秒。用戶可以完全控制 圖像質(zhì)量、數(shù)據(jù)格式和傳輸方式。所有圖像處理功能過程包括伽瑪曲線、白平衡、 度、色度等都可以通過 SCCB 接口編程。 OmmiVision 圖像傳感器應(yīng)用獨有的傳 感器技術(shù),通過減少或消除光學(xué)或電子缺陷如固定圖案噪聲、托尾、浮散等,提 高圖像質(zhì)量,得到清晰的穩(wěn)定的彩色圖像。(官方說明請進一步查看說明文檔,部分 中文版翻譯有出入,有能力的可以看英文版的)
SCCB?(后面會用到這里簡單講解一下)
?SCCB是歐姆尼圖像技術(shù)公司(OmniVision)開發(fā)的一種總線,并廣泛的應(yīng)用于OV系列圖像傳感器上,所以一般使用OV的圖像傳感器都離不開SCCB總線協(xié)議??梢酝ㄋ椎刂vSCCB有兩種工作模式,一主多從,一主一從模式。
參考正反面接線柱以及元器件(如下圖)
實物圖如下
OV7670 的特點有:
(1)高靈敏度、低電壓適合嵌入式應(yīng)用
(2)標準的 SCCB 接口,兼容 IIC 接口
(3)支持 RawRGB、RGB(GBR4:2:2,RGB565/RGB555/RGB444),YUV(4:2:2) 和 YCbCr( 4:2:2)輸出格式
(4)支持 VGA、 CIF,和從 CIF 到 40*30 的各種尺寸輸出
(5)支持自動曝光控制、自動增益控制、自動白平衡、自動消除燈光條紋、 自動黑電平校準等自動控制功能。同時支持色飽和度、色相、伽馬、銳度等設(shè)置。
(6)支持閃光燈
(7)支持圖像縮放
應(yīng)用,進行拍攝,畫面?zhèn)鬏斣诳刂瓢宓腡FT 屏幕上,下期更新拍照。
OV7670 傳感器 功能模塊:
1.感光整列( Image Array) OV7670 總共有 656488 個像素,其中 640480 個有效(即有效像素為 30W)。
2.時序發(fā)生器( Video Timing Generator) 時序發(fā)生器具有的功能包括:整列控制和幀率發(fā)生( 7 種不同格式輸出)、 內(nèi)部信號發(fā)生器和分布、幀率時序、自動曝光控制、輸出外部時序( VSYNC幀同步信號、 HREF/HSYNC同步信號 和 PCLK像素時鐘)。
3.模擬信號處理( Analog Processing) 模擬信號處理所有模擬功能,并包括:自動增益( AGC)和自動白平衡( AWB)。
4.A/D 轉(zhuǎn)換( A/D) 原始的信號經(jīng)過模擬處理器模塊之后 ,分 G 和 BR 兩路進入一個 10 位的 A/D 轉(zhuǎn)換器,A/D 轉(zhuǎn)換器工作在 12M 頻率,與像素頻率完全同步(轉(zhuǎn)換的頻率 和幀率有關(guān))。 除 A/D 轉(zhuǎn)換器外,該模塊還有以下三個功能: ①黑電平校正( BLC) ②U/V 通道延遲 ③A/D 范圍控制 A/D 范圍乘積和 A/D 的范圍控制共同設(shè)置 A/D 的范圍和最大值,允許用戶 2根據(jù)應(yīng)用調(diào)整圖片的亮度。
5.測試圖案發(fā)生器( Test Pattern Generator) 測試圖案發(fā)生器功能包括:八色彩色條圖案、漸變至黑白彩色條圖案和輸出 腳移位“ 1”。
6.數(shù)字處理器( DSP) 這個部分控制由原始信號插值到 RGB 信號的過程,并控制一些圖像質(zhì)量: ①邊緣銳化(二維高通濾波器) ②顏色空間轉(zhuǎn)換(原始信號到 RGB 或者 YUV/YCbYCr) ③RGB 色彩矩陣以消除串擾 ④色相和飽和度的控制 ⑤黑/白點補償 ⑥降噪 ⑦鏡頭補償 ⑧可編程的伽瑪 ⑨十位到八位數(shù)據(jù)轉(zhuǎn)換
7.縮放功能( Image Scaler) 這個模塊按照預(yù)先設(shè)置的要求輸出數(shù)據(jù)格式,能將 YUV/RGB 信號從 VGA 縮 小到 CIF 以下的任何尺寸。
8.數(shù)字視頻接口( Digital Video Port) 通過寄存器 COM2[1:0],調(diào)節(jié) IOL/IOH 的驅(qū)動電流,以適應(yīng)用戶的負載。
9.SCCB 接口( SCCB Interface) SCCB 接 口 控 制 圖 像 傳 感 器 芯 片 的 運 行 , 詳 細 使 用 方 法 參 照 《 OmniVisionTechnologies Seril Camera Control Bus(SCCB) Specification》 這個文檔。
10.LED 和閃光燈的輸出控制( LED and Storbe Flash Control Output) OV7670 有閃光燈模式,可以控制外接閃光燈或閃光 LED 的工作。 OV7670 的寄存器通過 SCCB 時序訪問并設(shè)置,SCCB 時序和 IIC 時序十分 類似,在這里我們不做介紹,請大家參考模塊的相關(guān)文檔。
重點定義:
VGA,即分辨率為 640480 的輸出模式;
QVGA,即分辨率為 320240 的輸出格式,也就是本手冊我們需要用到的格 式;
QQVGA,即分辨率為 160*120 的輸出格式;
PCLK,即像素時鐘,一個 PCLK 時鐘,輸出一個像素(或半個像素)。
VSYNC,即幀同步信號。
HREF /HSYNC,即行同步信號。
圖像輸出的控制條件
OV7670 的圖像數(shù)據(jù)輸出(通過 D[7:0])就是在 PCLK, VSYNC 和 HREF/ HSYNC 的控制下進行的。
首先看看行輸出時序,如圖所示:
-----上屬已經(jīng)初步了解了0V7670的原理和背景(下面市重點),下面學(xué)習(xí)OV7670 模塊使用方法-------------------------
下面圖像數(shù)據(jù)的存儲于讀取的過程分析
如何存儲圖像數(shù)據(jù)?
-OV7670 攝像頭模塊存儲圖像數(shù)據(jù)的過程為:等待 OV7670 同步信號→ FIFO 寫指針復(fù)位→FIFO 寫使能→等待第二個 OV7670 同步信號→FIFO 寫禁 止。通過以上 5 個步驟,我們就完成了 1 幀圖像數(shù)據(jù)的存儲
如何讀取圖像數(shù)據(jù)?
在存儲完一幀圖像以后,我們就可以開始讀取圖像數(shù)據(jù)了。讀取過程為: FIFO 讀指針復(fù)位→給 FIFO 讀時鐘( FIFO_RCLK)→讀取第一個像素高字節(jié)→ 給 FIFO 讀時鐘→讀取第一個像素低字節(jié)→給 FIFO 讀時鐘→讀取第二個像素 高字節(jié)→循環(huán)讀取剩余像素→結(jié)束。
原理圖如下所示
由上圖可以看出0v7670(圖片信號) ------傳輸數(shù)據(jù)到--------->FIFO------------------------>經(jīng)過輸出模塊------------------->mcu (我們拿到的圖片信息)
下面直接開始分析代碼函數(shù)的使用
初始化SCCB接口(前面講到使用sccb 進行控制圖像)/
初始化OV7670
設(shè)置圖像輸出窗口
幀中斷標記
更新LCD顯示
//初始化SCCB接口
//CHECK OK
void SCCB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_13); // 輸出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //輸輸出
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_3); // 輸出高
SCCB_SDA_OUT();
}
//初始化OV7670
//返回0:成功
//返回其他值:錯誤代碼
u8 OV7670_Init(void)
{
u8 temp;
u16 i=0;
//設(shè)置IO
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO, ENABLE); //使能相關(guān)端口時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PA8 輸入 上拉 **VSYNC**
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_8);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;// 端口配置SWD 禁止swj 因為默認的PB3和pb4 是Jtag下載占用
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4);
GPIO_InitStructure.GPIO_Pin = 0xff; //PC0~7 輸入 上拉
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_14|GPIO_Pin_15);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //SWD 禁止swj 因為默認的PB3和pb4 是Jtag下載占用的
SCCB_Init(); //初始化SCCB 的IO口
if(SCCB_WR_Reg(0x12,0x80))return 1; //復(fù)位SCCB
delay_ms(50);
//讀取產(chǎn)品型號
temp=SCCB_RD_Reg(0x0b);
if(temp!=0x73)return 2;
temp=SCCB_RD_Reg(0x0a);
if(temp!=0x76)return 2;
//初始化序列
for(i=0;i<sizeof(ov7670_init_reg_tbl)/sizeof(ov7670_init_reg_tbl[0]);i++)
{
//初始化寄存器序列及其對應(yīng)的值
SCCB_WR_Reg(ov7670_init_reg_tbl[i][0],ov7670_init_reg_tbl[i][1]); //SCCB_WR_Reg對ov7670_init_reg_tbl的寫入完成初始化
}
return 0x00; //ok
}
//設(shè)置圖像輸出窗口
//對QVGA設(shè)置。 可參考0v7670分辨率設(shè)置文檔
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_RD_Reg(0X03); //讀取Vref之前的值
temp&=0XF0;
temp|=((endx&0X03)<<2)|(sx&0X03);
SCCB_WR_Reg(0X03,temp); //設(shè)置Vref的start和end的最低2位
SCCB_WR_Reg(0X19,sx>>2); //設(shè)置Vref的start高8位
SCCB_WR_Reg(0X1A,endx>>2); //設(shè)置Vref的end的高8位
temp=SCCB_RD_Reg(0X32); //讀取Href之前的值
temp&=0XC0;
temp|=((endy&0X07)<<3)|(sy&0X07);
SCCB_WR_Reg(0X17,sy>>3); //設(shè)置Href的start高8位
SCCB_WR_Reg(0X18,endy>>3); //設(shè)置Href的end的高8位
}
//等待ov7670 幀同步信號(幀中斷標記是否開始)
u8 ov_sta; //幀中斷標記
void EXTI9_5_IRQHandler(void) //紅外遙控外部中斷
{
if(EXTI_GetITStatus(EXTI_Line8)==SET) //是8線的中斷
{
if(ov_sta<2)
{
if(ov_sta==0)
{
OV7670_WRST=0; //復(fù)位寫指針
OV7670_WRST=1;
OV7670_WREN=1; //允許寫入FIFO
}
else
{
OV7670_WREN=0;//禁止寫入FIFO
OV7670_WRST=0; //復(fù)位寫指針
OV7670_WRST=1;
}
ov_sta++; //幀中斷加1
}
}
EXTI_ClearITPendingBit(EXTI_Line8); //清除EXTI8線路掛起位
}
//更新LCD顯示
void camera_refresh(void)
{
u32 j;
u16 color;
if(ov_sta)//有幀中斷更新?
{
LCD_Display_Dir(1);
LCD_Set_Window(0,0,320-1,240-1);//將顯示區(qū)域設(shè)置到屏幕中央
OV7670_RRST=0; //開始復(fù)位讀指針
OV7670_RCK_L;
OV7670_RCK_H;
OV7670_RCK_L;
OV7670_RRST=1; //復(fù)位讀指針結(jié)束
OV7670_RCK_H;
for(j=0;j<76800;j++) //此種方式需清楚TFT內(nèi)部顯示方向控制寄存器值 速度較快
{
OV7670_RCK_L;
color=GPIOC->IDR&0XFF; //讀數(shù)據(jù)
OV7670_RCK_H;
color<<=8;
OV7670_RCK_L;
color|=GPIOC->IDR&0XFF; //讀數(shù)據(jù)
OV7670_RCK_H;
LCD_WriteData_Color(color);
}
ov_sta=0; //清零幀中斷標記
ov_frame++;
LCD_Display_Dir(0);
}
}
我們使用的話,直接將sccb 引入我們的項目,直接使用函數(shù)
sccb。h 文件
#ifndef __SCCB_H
#define __SCCB_H
#include "system.h"
//#define SCCB_SDA_IN() {GPIOG->CRH&=0XFF0FFFFF;GPIOG->CRH|=0X00800000;}
//#define SCCB_SDA_OUT() {GPIOG->CRH&=0XFF0FFFFF;GPIOG->CRH|=0X00300000;}
//IO操作函數(shù)
#define SCCB_SCL PDout(3) //SCL
#define SCCB_SDA PGout(13) //SDA
#define SCCB_READ_SDA PGin(13) //輸入SDA
#define SCCB_ID 0X42 //OV7670的ID
///
void SCCB_Init(void);
void SCCB_Start(void);
void SCCB_Stop(void);
void SCCB_No_Ack(void);
u8 SCCB_WR_Byte(u8 dat);
u8 SCCB_RD_Byte(void);
u8 SCCB_WR_Reg(u8 reg,u8 data);
u8 SCCB_RD_Reg(u8 reg);
#endif
sccb。c
```c
#include "system.h"
#include "sccb.h"
#include "SysTick.h"
void SCCB_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
void SCCB_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //輸入
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
//初始化SCCB接口
//CHECK OK
void SCCB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_13); // 輸出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //輸輸出
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_3); // 輸出高
SCCB_SDA_OUT();
}
//SCCB起始信號
//當時鐘為高的時候,數(shù)據(jù)線的高到低,為SCCB起始信號
//在激活狀態(tài)下,SDA和SCL均為低電平
void SCCB_Start(void)
{
SCCB_SDA=1; //數(shù)據(jù)線高電平
SCCB_SCL=1; //在時鐘線高的時候數(shù)據(jù)線由高至低
delay_us(50);
SCCB_SDA=0;
delay_us(50);
SCCB_SCL=0; //數(shù)據(jù)線恢復(fù)低電平,單操作函數(shù)必要
}
//SCCB停止信號
//當時鐘為高的時候,數(shù)據(jù)線的低到高,為SCCB停止信號
//空閑狀況下,SDA,SCL均為高電平
void SCCB_Stop(void)
{
SCCB_SDA=0;
delay_us(50);
SCCB_SCL=1;
delay_us(50);
SCCB_SDA=1;
delay_us(50);
}
//產(chǎn)生NA信號
void SCCB_No_Ack(void)
{
delay_us(50);
SCCB_SDA=1;
SCCB_SCL=1;
delay_us(50);
SCCB_SCL=0;
delay_us(50);
SCCB_SDA=0;
delay_us(50);
}
//SCCB,寫入一個字節(jié)
//返回值:0,成功;1,失敗.
u8 SCCB_WR_Byte(u8 dat)
{
u8 j,res;
for(j=0;j<8;j++) //循環(huán)8次發(fā)送數(shù)據(jù)
{
if(dat&0x80)SCCB_SDA=1;
else SCCB_SDA=0;
dat<<=1;
delay_us(50);
SCCB_SCL=1;
delay_us(50);
SCCB_SCL=0;
}
SCCB_SDA_IN(); //設(shè)置SDA為輸入
delay_us(50);
SCCB_SCL=1; //接收第九位,以判斷是否發(fā)送成功
delay_us(50);
if(SCCB_READ_SDA)res=1; //SDA=1發(fā)送失敗,返回1
else res=0; //SDA=0發(fā)送成功,返回0
SCCB_SCL=0;
SCCB_SDA_OUT(); //設(shè)置SDA為輸出
return res;
}
//SCCB 讀取一個字節(jié)
//在SCL的上升沿,數(shù)據(jù)鎖存
//返回值:讀到的數(shù)據(jù)
u8 SCCB_RD_Byte(void)
{
u8 temp=0,j;
SCCB_SDA_IN(); //設(shè)置SDA為輸入
for(j=8;j>0;j--) //循環(huán)8次接收數(shù)據(jù)
{
delay_us(50);
SCCB_SCL=1;
temp=temp<<1;
if(SCCB_READ_SDA)temp++;
delay_us(50);
SCCB_SCL=0;
}
SCCB_SDA_OUT(); //設(shè)置SDA為輸出
return temp;
}
//寫寄存器
//返回值:0,成功;1,失敗.
u8 SCCB_WR_Reg(u8 reg,u8 data)
{
u8 res=0;
SCCB_Start(); //啟動SCCB傳輸
if(SCCB_WR_Byte(SCCB_ID))res=1; //寫器件ID
delay_us(100);
if(SCCB_WR_Byte(reg))res=1; //寫寄存器地址
delay_us(100);
if(SCCB_WR_Byte(data))res=1; //寫數(shù)據(jù)
SCCB_Stop();
return res;
}
//讀寄存器
//返回值:讀到的寄存器值
u8 SCCB_RD_Reg(u8 reg)
{
u8 val=0;
SCCB_Start(); //啟動SCCB傳輸
SCCB_WR_Byte(SCCB_ID); //寫器件ID
delay_us(100);
SCCB_WR_Byte(reg); //寫寄存器地址
delay_us(100);
SCCB_Stop();
delay_us(100);
//設(shè)置寄存器地址后,才是讀
SCCB_Start();
SCCB_WR_Byte(SCCB_ID|0X01); //發(fā)送讀命令
delay_us(100);
val=SCCB_RD_Byte(); //讀取數(shù)據(jù)
SCCB_No_Ack();
SCCB_Stop();
return val;
}
主函數(shù)main文章來源:http://www.zghlxwxcb.cn/news/detail-407618.html
extern u8 ov_sta;
extern u8 ov_frame; //在time.c里面定義
更新LCD顯示
void camera_refresh(void)
{
u32 j;
u16 color;
if(ov_sta)//有幀中斷更新?
{
LCD_Display_Dir(1);
LCD_Set_Window(0,0,320-1,240-1);//將顯示區(qū)域設(shè)置到屏幕中央
OV7670_RRST=0; //開始復(fù)位讀指針
OV7670_RCK_L;
OV7670_RCK_H;
OV7670_RCK_L;
OV7670_RRST=1; //復(fù)位讀指針結(jié)束
OV7670_RCK_H;
for(j=0;j<76800;j++) //此種方式需清楚TFT內(nèi)部顯示方向控制寄存器值 速度較快
{
OV7670_RCK_L;
color=GPIOC->IDR&0XFF; //讀數(shù)據(jù)
OV7670_RCK_H;
color<<=8;
OV7670_RCK_L;
color|=GPIOC->IDR&0XFF; //讀數(shù)據(jù)
OV7670_RCK_H;
LCD_WriteData_Color(color);
}
ov_sta=0; //清零幀中斷標記
ov_frame++;
LCD_Display_Dir(1); //設(shè)置掃描方向
//定位顏色識別區(qū)域
if(Trace(&condition, &result))
{
LCD_DrawRectangle( result.x-result.w/2, result.y-result.h/2, result.x-result.w/2+result.w, result.y-result.h/2+result.h);
LCD_DrawRectangle( result.x-2, result.y-2,result.x+2, result.y+2);
}
}
}
const u8*LMODE_TBL[5]={"Auto","Sunny","Cloudy","Office","Home"};
const u8*EFFECTS_TBL[7]={"Normal","Negative","B&W","Redish","Greenish","Bluish","Antique"}; //7種特效
int main()
{
u8 i=0;
u8 key;
u8 lightmode=0,saturation=2,brightness=2,contrast=2;
u8 effect=0;
u8 sbuf[15];
u8 count;
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷優(yōu)先級分組 分2組
LED_Init();
USART1_Init(115200);
TFTLCD_Init(); //LCD初始化
KEY_Init();
EN25QXX_Init(); //初始化EN25Q128
my_mem_init(SRAMIN); //初始化內(nèi)部內(nèi)存池
FRONT_COLOR=RED;//設(shè)置字體為紅色
LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,16,"PRECHIN STM32F1");
LCD_ShowString(10,30,tftlcd_data.width,tftlcd_data.height,16,"www.prechin.net");
LCD_ShowString(10,50,tftlcd_data.width,tftlcd_data.height,16,"OV7670 Test");
while(OV7670_Init())//初始化OV7670
{
LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 Error!");
delay_ms(200);
LCD_Fill(10,80,239,206,WHITE);
delay_ms(200);
}
LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 OK! ");
delay_ms(1500);
OV7670_Light_Mode(0);
OV7670_Color_Saturation(2);
OV7670_Brightness(2);
OV7670_Contrast(2);
OV7670_Special_Effects(0);
TIM4_Init(10000,7199); //10Khz計數(shù)頻率,1秒鐘中斷
EXTI8_Init();
OV7670_Window_Set(12,176,240,320); //設(shè)置窗口
OV7670_CS=0;
LCD_Clear(BLACK);
while(1)
{
key=KEY_Scan(0);
if(key)count=20;
switch(key)
{
case KEY_UP_PRESS: //燈光模式設(shè)置
lightmode++;
if(lightmode>4)lightmode=0;
OV7670_Light_Mode(lightmode);
sprintf((char*)sbuf,"%s",LMODE_TBL[lightmode]);
break;
case KEY1_PRESS: //飽和度
saturation++;
if(saturation>4)saturation=0;
OV7670_Color_Saturation(saturation);
sprintf((char*)sbuf,"Saturation:%d",(char)saturation-2);
break;
case KEY2_PRESS: //亮度
brightness++;
if(brightness>4)brightness=0;
OV7670_Brightness(brightness);
sprintf((char*)sbuf,"Brightness:%d",(char)brightness-2);
break;
case KEY0_PRESS: //對比度
contrast++;
if(contrast>4)contrast=0;
OV7670_Contrast(contrast);
sprintf((char*)sbuf,"Contrast:%d",(char)contrast-2);
break;
}
if(count)
{
count--;
LCD_ShowString((tftlcd_data.width-240)/2+30,(tftlcd_data.height-320)/2+60,200,16,16,sbuf);
}
camera_refresh();//更新顯示
i++;
if(i%20==0)
{
LED1=!LED1;
}
// delay_ms(5);
}
}
總結(jié):
攝像頭模塊內(nèi)容相對以往 比較多,獲取圖像,圖像轉(zhuǎn)化-再到顯示-幀數(shù)更新顯示。
SCCB 庫的使用
注釋,代碼我學(xué)習(xí)使用的是普中的代碼f103zet6,戰(zhàn)艦V3 ,需要完整版本的demo 私信
上一節(jié) stm32 MPU6050 6軸姿態(tài)傳感器的介紹與DMP的應(yīng)用
文章來源地址http://www.zghlxwxcb.cn/news/detail-407618.html
到了這里,關(guān)于stm32 OV7670攝像頭模塊的介紹以及應(yīng)用(SCCB的使用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!