OV7670 是 OV(OmniVision)公司生产的一颗 1/6 寸的 CMOS VGA 图像传感器。该传感器体积小、工作电压低,提供单片 VGA 摄像头和影像处理器的所有功能。通过 SCCB 总线控制,可以输出整帧、子采样、取窗口等方式的各种分辨率 8 位影像数据。该产品 VGA图像最高达到 30 帧/秒。用户可以完全控制图像质量、数据格式和传输方式。所有图像处理功能过程包括伽玛曲线、白平衡、度、色度等都可以通过 SCCB 接口编程。OmmiVision 图像传感器应用独有的传感器技术,通过减少或消除光学或电子缺陷如固定图案噪声、托尾、浮散等,提高图像质量,得到清晰的稳定的彩色图像。
但是由于后期如ov5640与ov2460等高像素高质量的摄像头的登场,导致ov7670只能依据fifo模块生存在像f1系列单片机这样的低速平台中,高速平台F4与F7对其都不友好。
笔者由于购买时搭配的是ov7670带fifo与原子f429阿波罗开发板,在网上找不到现成的移植案例,无奈之下自己写了一篇,供大家参考。
ov7670.h库的移植
引脚定义的修改与原理图
部分修改后代码
编译成果
ov7670.h库的移植
在 F107 程序 的 HARDWARE文件夹里面,copy出 ov7670 文件夹,移植进 F429的 HARDWARE里
引脚定义的修改与原理图
引脚修改这里就不再啰嗦,读者可自行完成。
修改前代码
int main(void)
{
u8 key;
u8 t;
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
usart2_init(921600); //初始化USART2
usmart_dev.init(90); //初始化USMART
LED_Init(); //初始化LED
KEY_Init(); //初始化按键
SDRAM_Init(); //初始化SDRAM
LCD_Init(); //初始化LCD
TIM3_Init(10000-1,9000-1); //10Khz计数,1秒钟中断一次
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(30,50,200,16,16,“Apollo STM32F4/F7”);
LCD_ShowString(30,70,200,16,16,“OV5640 TEST”);
LCD_ShowString(30,90,200,16,16,“ATOM@ALIENTEK”);
LCD_ShowString(30,110,200,16,16,“2016/1/16”);
while(1)//初始化OV5640
{
LCD_ShowString(30,130,240,16,16,“OV5640 ERR”);
delay_ms(200);
LCD_Fill(30,130,239,170,WHITE);
delay_ms(200);
LED0=!LED0;
}
LCD_ShowString(30,130,200,16,16,“OV5640 OK”);
while(1)
{
// key=KEY_Scan(0);
// if(key==KEY0_PRES){ovx_mode=0;break;} //RGB565模式
// else if(key==KEY1_PRES){ovx_mode=1;break;} //JPEG模式
// t++;
// if(t==100)LCD_ShowString(30,150,230,16,16,“KEY0:RGB565 KEY1:JPEG”); //闪烁显示提示信息
// if(t==200)
// {
// LCD_Fill(30,150,210,150+16,WHITE);
// t=0;
// LED0=!LED0;
// }
// delay_ms(5);
}
// if(ovx_mode==1)jpeg_test();
// else rgb565_test();
}
修改后代码
int main(void)
{
u8 key,t;
u8 lightmode=0,saturation=2,brightness=2,contrast=2;
u8 effect=0;
u8 i=0;
u8 msgbuf[15]; //消息缓存区
u8 tm=0;
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
usart2_init(921600); //初始化USART2
usmart_dev.init(90); //初始化USMART
LED_Init(); //初始化LED
KEY_Init(); //初始化按键
SDRAM_Init(); //初始化SDRAM
LCD_Init(); //初始化LCD
TIM3_Init(10000-1,9000-1);
delay_init(180); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为 115200
usmart_dev.init(72); //初始化USMART
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init(); //初始化按键
LCD_Init(); //初始化LCD
TPAD_Init(6); //触摸按键初始化
POINT_COLOR=RED; //设置字体为红色
LCD_ShowString(30,50,200,16,16,“Apollo STM32F4/F7”);
LCD_ShowString(30,70,200,16,16,“OV5640 TEST”);
LCD_ShowString(30,90,200,16,16,“ATOM@ALIENTEK”);
LCD_ShowString(30,110,200,16,16,“2016/1/16”);
while(OV7670_Init())//初始化OV7670
{
LCD_ShowString(30,230,200,16,16,“OV7670 Error!!”);
delay_ms(200);
LCD_Fill(30,230,239,246,WHITE);
delay_ms(200);
LED0=!LED0;
}
LCD_ShowString(30,230,200,16,16,“OV7670”);
delay_ms(1500);
OV7670_Light_Mode(lightmode);
OV7670_Color_Saturation(saturation);
OV7670_Brightness(brightness);
OV7670_Contrast(contrast);
OV7670_Special_Effects(effect);
// TIM6_Int_Init(10000,7199); //10Khz计数频率,1秒钟中断
// EXTI8_Init(); //使能定时器捕获
OV7670_Window_Set(12,176,240,320); //设置窗口
OV7670_CS=0;
LCD_Clear(BLACK);
while(1)
{
key=KEY_Scan(0);//不支持连按
if(key)
{
tm=20;
switch(key)
{
case KEY0_PRES: //灯光模式Light Mode
lightmode++;
if(lightmode》4)lightmode=0;
OV7670_Light_Mode(lightmode);
sprintf((char*)msgbuf,“%s”,LMODE_TBL[lightmode]);
break;
case KEY1_PRES: //饱和度Saturation
saturation++;
if(saturation》4)saturation=0;
OV7670_Color_Saturation(saturation);
sprintf((char*)msgbuf,“Saturation:%d”,(signed char)saturation-2);
break;
case KEY2_PRES: //亮度Brightness
brightness++;
if(brightness》4)brightness=0;
OV7670_Brightness(brightness);
sprintf((char*)msgbuf,“Brightness:%d”,(signed char)brightness-2);
break;
case WKUP_PRES: //对比度Contrast
contrast++;
if(contrast》4)contrast=0;
OV7670_Contrast(contrast);
sprintf((char*)msgbuf,“Contrast:%d”,(signed char)contrast-2);
break;
}
}
// if(TPAD_Scan(0))//检测到触摸按键
// {
// effect++;
// if(effect》6)effect=0;
// OV7670_Special_Effects(effect);//设置特效
// sprintf((char*)msgbuf,“%s”,EFFECTS_TBL[effect]);
// tm=20;
// }
camera_refresh();//更新显示
if(tm)
{
LCD_ShowString((lcddev.width-240)/2+30,(lcddev.height-320)/2+60,200,16,16,msgbuf);
tm--;
}
i++;
if(i==15)//DS0闪烁。
{
i=0;
LED0=!LED0;
}
}
}