/*
OV7670模塊 STM32函數(shù)
選用STM32F103RBT6芯片
TFT驅(qū)動IC為 R61505V
程序中 用到的TFT 為 我們店的 2.4寸TFT 驅(qū)動芯片為 R61505V
TFT用到的GPIO PB為數(shù)據(jù)口 PC.6 CS PC.7 RS PC.8 WR PC.9 RD PC.10 RES
此函數(shù) 用寄存器方式配置GPIO 在TFT的數(shù)據(jù) 命令腳配置上用的是寄存器 這樣能大幅度提高輸出速度
攝像頭方面
攝像頭 數(shù)據(jù)口 為PA口 AO-A7
SCL PC11
SDA PC12
OE PC3 //片選信號(OE)
WRST PC4 //寫指針復(fù)位
RRST PC2 //讀指針復(fù)位
RCLK PC1 //讀數(shù)據(jù)時鐘
WEN PC5 //寫入FIFO使能
VSY PD2 //同步信號檢測IO
整個程序流程介紹
初始化TFT
初始化ov7670 ov7670是通過SCCB 初始化的 即 SCL 和SDA就可以初始化OV7670 SDA SCL類似于I2C效果
所以在調(diào)模塊前 一定要確定OV7670是否已經(jīng)初始化
開啟中斷 判斷幀數(shù)據(jù)是否接收
死循環(huán) 讀取并顯示 攝像數(shù)據(jù)
*/
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "tft.h"
#include "led.h"
#include "ov7670.h"
#include "gui.h"
#include "usart.h"
#include "PID.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_9)
#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)
void coordinate_output(void);
extern u8 ov_sta; //幀次數(shù) 置位標志位
struct{
u8 photo;
u8 pub_buf[14401];//120*120
char buf[200];
}CAM;
//更新LCD顯示
void camera_refresh(void)
{
u32 j;
u16 color,n565Color;
u8 cRed=0,cBlue=0,cGreen=0;
TFT_SCAN(5); //設(shè)置TFT掃描方向 為從下到上 從右到左
Address_set(60,0,179,119,0,0); //設(shè)置顯示范圍
if(ov_sta==2) //判斷緩存區(qū)是否存好攝像數(shù)據(jù)
{
OV7670_RRST_0; //開始復(fù)位讀指針
OV7670_RCK_0;
OV7670_RCK_1;
OV7670_RCK_0;
OV7670_RRST_1; //復(fù)位讀指針結(jié)束
OV7670_RCK_1;
TFT_RS_1; //寫數(shù)據(jù)線拉高 為提高寫入速度
//此用法 是將 下面寫數(shù)據(jù)的步驟完全拆開 主要是為了提高顯示速度 (下面注釋部分為參考部分)
for(j=0;j<14400;j++) //分辨率為240x320 每個顏色點要兩個字節(jié) 所以 240x320x2=76800 ?
{
OV7670_RCK_0; //每一次時鐘跳變 讀一次數(shù)據(jù)
color=GPIOC->IDR&0XFF; //讀數(shù)據(jù) 讀取顏色高字節(jié)數(shù)據(jù)
OV7670_RCK_1;
color<<=8; //左移8位 將高字節(jié)移到高8位 為接收低8位字節(jié)做準備
OV7670_RCK_0;
color|=GPIOC->IDR&0XFF; //讀數(shù)據(jù) 讀取顏色低字節(jié)數(shù)據(jù) 并轉(zhuǎn)化為16位 565 顏色數(shù)據(jù)
OV7670_RCK_1;
cRed = ((color & 0xf800)>>11);
CAM.pub_buf[j]=cRed;
n565Color = (cRed << 11) + (cGreen << 5) + (cBlue << 0);
GPIOB->ODR=n565Color; //對TFT并口快速寫數(shù)據(jù)
TFT_WR_0; //開始寫入
TFT_WR_1;
}
coordinate_output();
EXTI_ClearITPendingBit(EXTI_Line2); //清除LINE8上的中斷標志位
ov_sta=0; //開始下一次采集
}
}
u16 blight=15;//亮度判斷更改這里
void coordinate_output(void)
{
u16 i,j,k;
xmax=ymax=0;
xmin=ymin=119;
for(i=0;i<120;i++)
{
for(j=0;j<120;j++)
{
if(CAM.pub_buf[(i*120)+j]>=blight)
{
if(i>1&&i<119&&j<119&&j>1)//如果i值大于8且小于136(限制小球在8~136行),同理,限制小球在16~160列
{
if(j>xmax) {xmax=j;} //不斷更新邊緣,直到找到小球的直徑
if(j<xmin) {xmin=j;}//不斷更新邊緣,直到找到小球的直徑
if(i>ymax) {ymax=i;}//不斷更新邊緣,直到找到小球的直徑
if(i<ymin) {ymin=i;}//不斷更新邊緣,直到找到小球的直徑
}
}
}
}
for(k=0;k<14400;k++)
{
CAM.pub_buf[k]=0x00;
}
x=(xmax+xmin)/2;
y=(ymax+ymin)/2;
if(x<1){x=1;}
if(x>119){x=119;}
if(y<1){y=1;}
if(y>119){y=119;}
if(x!=0&&y!=0)
{
// GUI_sprintf_hzstr16x(20,200," ",Red,White);
sprintf(CAM.buf,"X:%d ",x);
GUI_sprintf_hzstr16x(20,200,CAM.buf,Red,White);
sprintf(CAM.buf,"Y:%d ",y);
GUI_sprintf_hzstr16x(80,200,CAM.buf,Red,White);
printf("X:%d",x);
printf("Y:%d",y);
printf("\r\n");
}
}
void disp_picture(void)
{
u16 i,j=0;
u16 COLOR;
u8 aRed=0,aBlue=0,aGreen=0;
coordinate_output();
TFT_SCAN(5);
Address_set(60,0,179,119,0,0);
TFT_RS_1;
for(i=0;i<14400;i++)
{
aRed=CAM.pub_buf;
printf("%d ",aRed);
j++;
if(j>=120){printf("\r\n");j=0;}
COLOR = (aRed << 11) + (aGreen << 5) + (aBlue << 0);
GPIOB->ODR=COLOR; //對TFT并口快速寫數(shù)據(jù)
TFT_WR_0; //開始寫入
TFT_WR_1;
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
int main(void)
{
u8 lightmode=2,saturation=3,brightness=2,contrast=2;
u8 effect=0,flag=0;
delay_init(); //延時函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Lcd_Init(); //LCD 初始化
LED_Init();
uart_init(115200);
TIM2_Int_Init(1,1799);
TFT_CS(0); //打開LCD片選使能
GUI_Clear(White); //清屏
while(OV7670_Init())//初始化OV7670
{
GUI_sprintf_hzstr16x(20,150,"OV7670 Error!! ",Blue,White);
delay_ms(200);
printf("OV7670 ERROR!!!!!\r\n");
}
GUI_Clear(White); //清屏 初始化成功后 紅色清屏
CAM.photo=0;
// delay_ms(1500);
//攝像頭 參數(shù)設(shè)置 屏蔽后為默認效果
OV7670_Light_Mode(lightmode);
OV7670_Color_Saturation(saturation);
OV7670_Brightness(brightness);
OV7670_Contrast(contrast);
OV7670_Special_Effects(effect);
EXTI2_Init(); //初始化中斷線
OV7670_Window_Set(10,174,120,120);
OV7670_CS=0;
while(1) //死循環(huán)顯示 攝像數(shù)據(jù)
{
camera_refresh();
// test_motor();
}
}
|