找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8854|回复: 3
打印 上一主题 下一主题
收起左侧

OV7670摄像头实验,任意窗口输出,灰度输出

[复制链接]
跳转到指定楼层
楼主
ID:223055 发表于 2017-8-9 17:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.实验描述:
通过config_ov7670_OutPut(u16 xsta,u16 ysta,u16 width,u16 height,u8 ouput_mode)可以设置摄像头显示图片的位置,窗口的大小,显示的模式(彩色还是灰度)。

2.说明:
  灰度输出:将摄像头设置输出为YUV格式(YUYV输出,意思就是第一个字节是Y,第二个字节是U,第三个字节是Y,第四个字节是V轮流输出),取Y分量,去掉U,V,并将Y分量转换为RGB565就可以显示灰度图像了。

3.如何提高帧数:
  a:提高摄像头输出的帧数
  当ov_sta==2的时候们才开始显示图像。如果摄像头能输出30FPS,那么在液晶显示速度足够的情况下,最多只能显示15FPS,所以想要提高显示帧率可以提高摄像头输出的帧率。
  这里有一个公式:1s=510*784*2*2*PCLK*摄像头输出帧数。(至于原理可以看下时序图) 。这里初始化的代码设置的像素输出时钟PCLK为48MHZ,所以我们只能输出30FPS,可以通过设置0x6b将PCLK的时钟设置为96MHZ(最高了,外部输入时钟为12MHZ 这了8倍频),那么就可以输出60FPS,就可以提高显示的帧率了。
  b:送数据的显示速度,例如 用FSMC控制液晶,快速IO,移位等等。

4.如何调试:
利用usmart调试摄像头很方便的哦, 将函数config_ov7670_OutPut(u16 xsta,u16 ysta,u16 width,u16 height,u8 ouput_mode)和SCCB_WR_Reg(u8 reg,u8 data)添加到usmart_config.c文件就好了^_^


源程序:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "key.h"
  4. #include "sys.h"
  5. #include "lcd.h"
  6. #include "usart.h"         
  7. #include "string.h"
  8. #include "ov7670.h"
  9. #include "tpad.h"
  10. #include "timer.h"
  11. #include "exti.h"
  12. #include "usmart.h"

  13. extern u8 ov_sta;        //在exit.c里面定义
  14. extern u8 ov_frame;        //在timer.c里面定义       
  15. extern u8 data_ready;       

  16. u16 color_r;
  17. u16 color_g;
  18. u16 color_b;




  19. //设置CPU的频率
  20. void ov7670_clock_set(u8 PLL)
  21. {
  22.         u8 temp=0;          
  23.         RCC->CFGR&=0XFFFFFFFC;       
  24.         RCC->CR&=~0x01000000;            
  25.         RCC->CFGR&=~(0XF<<18);       
  26.         PLL-=2;//抵消2个单位
  27.         RCC->CFGR|=PLL<<18;          
  28.         RCC->CFGR|=1<<16;                  //PLLSRC ON  
  29.         FLASH->ACR|=0x12;          
  30.         RCC->CR|=0x01000000;          //PLLON
  31.         while(!(RCC->CR>>25));       
  32.         RCC->CFGR|=0x02;       
  33.         while(temp!=0x02)     
  34.         {   
  35.                 temp=RCC->CFGR>>2;
  36.                 temp&=0x03;
  37.         }   
  38. }

  39. //更新LCD显示
  40. void camera_refresh()
  41. {
  42.         u32 i,j;
  43.         u16 color;
  44.         if(ov_sta==2)
  45.         {
  46.                 LCD_Scan_Dir(U2D_L2R);                //从上到下,从左到右
  47.                 LCD_SetCursor(0x00,0x0000);        //设置光标位置
  48.                 LCD_WriteRAM_Prepare();     //开始写入GRAM       
  49.                 OV7670_RRST=0;                                //开始复位读指针
  50.                 OV7670_RCK_L;
  51.                 OV7670_RCK_H;
  52.                 OV7670_RCK_L;
  53.                 OV7670_RRST=1;                                //复位读指针结束
  54.                 OV7670_RCK_H;  
  55.                 if(ov7670_config.mode){
  56.                         for(i=0; i<ov7670_config.height; i++)
  57.                         {
  58.                         //        LCD_SetCursor(i+ov7670_config.xsta,ov7670_config.ysta);        //设置光标位置
  59.                         //        LCD_WriteRAM_Prepare();     //开始写入GRAM       
  60.                                 for(j=0; j<ov7670_config.width; j++)
  61.                                 {
  62.                                         OV7670_RCK_L;
  63.                                         color = GPIOC->IDR&0XFF;        //读数据
  64.                                         OV7670_RCK_H;
  65.                                        
  66.                                         color<<=8;
  67.                                         OV7670_RCK_L;//因为设置的是 YUYV输出,第二个字节没用,不需要读
  68.                                 //        color |= GPIOC->IDR&0XFF;        //
  69.                                         OV7670_RCK_H;
  70.                                        
  71.                                        
  72.                                         color_r = color&0xf800;
  73.                                         color_b = color>>11;
  74.                                         color >>=5;
  75.                                         color_g =color&0x07e0;
  76.                                        
  77.                                         LCD->LCD_RAM= color_r + color_g + color_b;   
  78.                                 }
  79.          
  80.                         }
  81.                 }else{
  82.                         for(i=0; i<ov7670_config.height; i++)
  83.                         {
  84.                         //        LCD_SetCursor(i+ov7670_config.xsta,ov7670_config.ysta);        //设置光标位置
  85.                         //        LCD_WriteRAM_Prepare();     //开始写入GRAM       
  86.                                 for(j=0; j<ov7670_config.width; j++)
  87.                                 {
  88.                                         OV7670_RCK_L;
  89.                                         color = GPIOC->IDR&0XFF;        //读数据
  90.                                         OV7670_RCK_H;
  91.                                        
  92.                                         color<<=8;
  93.                                         OV7670_RCK_L;
  94.                                         color |= GPIOC->IDR&0XFF;        //读数据
  95.                                         OV7670_RCK_H;
  96.                                        
  97.                                         LCD->LCD_RAM=color;   
  98.                                 }
  99.          
  100.                         }
  101.                 }               
  102.                 EXTI_ClearITPendingBit(EXTI_Line8);  //清除LINE8上的中断标志位
  103.                 ov_sta=0;                                        //开始下一次采集
  104.                 ov_frame++;
  105.           LCD_Scan_Dir(DFT_SCAN_DIR);        //恢复默认扫描方向
  106.         }
  107. }       


  108. int main(void)
  109. {         
  110.         delay_init();                     //延时函数初始化          
  111.         NVIC_Configuration();          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  112.         uart_init(9600);                 //串口初始化为9600
  113.         LED_Init();                             //LED端口初始化
  114.         LCD_Init();       
  115.         KEY_Init();                
  116.         TPAD_Init(72);                        //触摸按键初始化
  117.         usmart_dev.init(72);        //初始化USMART                            
  118.         POINT_COLOR=RED;//设置字体为红色
  119.         LCD_ShowString(60,50,200,16,16,"WarShip STM32");       
  120.         LCD_ShowString(60,70,200,16,16,"OV7670 TEST");       
  121.         LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
  122.         LCD_ShowString(60,110,200,16,16,"2012/9/14");           
  123.           LCD_ShowString(60,130,200,16,16,"OV7670 Init...");          
  124.         while(OV7670_Init())//初始化OV7670
  125.         {
  126.                 LCD_ShowString(60,130,200,16,16,"OV7670 Error!!");
  127.                 delay_ms(200);
  128.             LCD_Fill(60,130,239,246,WHITE);
  129.                 delay_ms(200);
  130.         }
  131.         LCD_ShowString(60,130,200,16,16,"OV7670 Init OK");
  132.           

  133.        
  134.         TIM6_Int_Init(10000,7199);                        //10Khz计数频率,1秒钟中断                                                                          
  135.         EXTI8_Init();                                                //使能定时器捕获
  136.           OV7670_CS=0;                       
  137.        
  138.         config_ov7670_OutPut(20,60,320,240,1);

  139.         while(1)
  140.         {       
  141.                 camera_refresh();//更新显示
  142.         }
  143. }

复制代码
源码以及参考的文档见附件:

摄像头实验(彩色,灰度,任意窗口).rar (359.28 KB, 下载次数: 120)
ov7670摄像头分辨率设置方法详解:
http://www.51hei.com/bbs/dpj-92272-1.html




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:138247 发表于 2019-4-4 16:16 | 只看该作者

谢谢分享。。。
回复

使用道具 举报

板凳
ID:545992 发表于 2019-5-23 23:12 | 只看该作者
谢谢分享
回复

使用道具 举报

地板
ID:583148 发表于 2019-7-21 09:41 | 只看该作者
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表