STM327725和7670二值化程序

#include "sys.h"
#include "ov7725.h"
#include "ov7725config.h"  
#include "delay.h"
#include "usart.h"   
#include "sccb.h" 
#include "lcd.h"
#include "timer.h"
#include "exti.h"
//
//ALIENTEK精英STM32开发板
//OV7725 驱动代码   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2017/11/1
//版本:V1.0                         
//
 //更新LCD显示
u32 j,i,x=0,y=0;
 u16 color; 
 u8 gm_red, gm_green, gm_blue; 
 u8 tm=0;
 int r,tt; 
  u8 lightmode=0,saturation=2,contrast=2;
 u8 effect=0; 
      
 u8 msgbuf[15];    //消息缓存区
 extern u8 ov_sta;
 extern u8 ov_frame;
//初始化OV7725
//返回0:成功
//返回其他值:错误代码
u8 OV7725_Init(void)
{
 u16 i=0;
 u16 reg=0;
 //设置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);//使能相关端口时钟
 
 GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;  //PA8 输入 上拉
 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;  // 端口配置
  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
 
 SCCB_Init();          //初始化SCCB 的IO口 
  if(SCCB_WR_Reg(0x12,0x80))return 1; //软复位OV7725
 delay_ms(50);
 reg=SCCB_RD_Reg(0X1c);  //读取厂家ID 高八位
 reg<<=8;
 reg|=SCCB_RD_Reg(0X1d);  //读取厂家ID 低八位
 if(reg!=OV7725_MID)
 {
  printf("MID:%d\r\n",reg);
  return 1;
 }
 reg=SCCB_RD_Reg(0X0a);  //读取厂家ID 高八位
 reg<<=8;
 reg|=SCCB_RD_Reg(0X0b);  //读取厂家ID 低八位
 if(reg!=OV7725_PID)
 {
  printf("HID:%d\r\n",reg);
  return 2;
 }  
  //初始化 OV7725,采用QVGA分辨率(320*240) 
 for(i=0;i<sizeof(ov7725_init_reg_tb1)/sizeof(ov7725_init_reg_tb1[0]);i++)
 {        
     SCCB_WR_Reg(ov7725_init_reg_tb1[i][0],ov7725_init_reg_tb1[i][1]);
  }
   return 0x00;  //ok
}

//OV7725功能设置
//白平衡设置
//0:自动模式
//1:晴天
//2,多云
//3,办公室
//4,家里
//5,夜晚
void OV7725_Light_Mode(u8 mode)
{
 switch(mode)
 {
  case 0: //Auto,自动模式
   SCCB_WR_Reg(0x13, 0xff); //AWB on
   SCCB_WR_Reg(0x0e, 0x65);
   SCCB_WR_Reg(0x2d, 0x00);
   SCCB_WR_Reg(0x2e, 0x00);
   break;
  case 1://sunny,晴天
   SCCB_WR_Reg(0x13, 0xfd); //AWB off
   SCCB_WR_Reg(0x01, 0x5a);
   SCCB_WR_Reg(0x02, 0x5c);
   SCCB_WR_Reg(0x0e, 0x65);
   SCCB_WR_Reg(0x2d, 0x00);
   SCCB_WR_Reg(0x2e, 0x00);
   break; 
  case 2://cloudy,多云
   SCCB_WR_Reg(0x13, 0xfd); //AWB off
   SCCB_WR_Reg(0x01, 0x58);
   SCCB_WR_Reg(0x02, 0x60);
   SCCB_WR_Reg(0x0e, 0x65);
   SCCB_WR_Reg(0x2d, 0x00);
   SCCB_WR_Reg(0x2e, 0x00);
   break; 
  case 3://office,办公室
   SCCB_WR_Reg(0x13, 0xfd); //AWB off
   SCCB_WR_Reg(0x01, 0x84);
   SCCB_WR_Reg(0x02, 0x4c);
   SCCB_WR_Reg(0x0e, 0x65);
   SCCB_WR_Reg(0x2d, 0x00);
   SCCB_WR_Reg(0x2e, 0x00);
   break; 
  case 4://home,家里
   SCCB_WR_Reg(0x13, 0xfd); //AWB off
   SCCB_WR_Reg(0x01, 0x96);
   SCCB_WR_Reg(0x02, 0x40);
   SCCB_WR_Reg(0x0e, 0x65);
   SCCB_WR_Reg(0x2d, 0x00);
   SCCB_WR_Reg(0x2e, 0x00);
   break; 
  case 5://night,夜晚
   SCCB_WR_Reg(0x13, 0xff); //AWB on
   SCCB_WR_Reg(0x0e, 0xe5);
   break;
 }
}   
//色度设置
//sat:-4~+4
void OV7725_Color_Saturation(s8 sat)
{
  if(sat>=-4 && sat<=4)
 { 
  SCCB_WR_Reg(USAT,(sat+4)<<4);
  SCCB_WR_Reg(VSAT,(sat+4)<<4);
 }
}
//亮度设置
//bright:-4~+4
void OV7725_Brightness(s8 bright)
{
 u8 bright_value,sign;
   switch(bright)
 {
  case 4:
   bright_value = 0x48;
   sign = 0x06;
   break;
  case 3:
   bright_value = 0x38;
   sign = 0x06;  
   break; 
  case 2:
   bright_value = 0x28;
   sign = 0x06;   
   break; 
  case 1:
   bright_value = 0x18;
   sign = 0x06;   
   break;
  case 0:
   bright_value = 0x08;
   sign = 0x06;   
   break; 
  case -1:
   bright_value = 0x08;
   sign = 0x0e;  
   break;  
  case -2:
   bright_value = 0x18;
   sign = 0x0e;  
   break; 
  case -3:
   bright_value = 0x28;
   sign = 0x0e;  
   break; 
  case -4:
   bright_value = 0x38;
   sign = 0x0e;  
   break; 
 }
 SCCB_WR_Reg(BRIGHT, bright_value);
 SCCB_WR_Reg(SIGN, sign);
}
//对比度设置
//contrast:-4~+4
void OV7725_Contrast(s8 contrast)
{
 if(contrast >= -4 && contrast <=4)
 {
  SCCB_WR_Reg(CNST,(0x30-(4-contrast)*4));
 }
}
//特效设置
//0:普通模式   
//1,负片
//2,黑白  
//3,偏红色
//4,偏绿色
//5,偏蓝色
//6,复古    
void OV7725_Special_Effects(u8 eft)
{
 switch(eft)
 {
  case 0://正常
   SCCB_WR_Reg(0xa6, 0x06);//TSLB设置
   SCCB_WR_Reg(0x60, 0x80);//MANV,手动V值
   SCCB_WR_Reg(0x61, 0x80);//MANU,手动U值
   break;
  case 1://负片
   SCCB_WR_Reg(0xa6, 0x46);
   break;
  case 2://黑白
   SCCB_WR_Reg(0xa6, 0x26);
   SCCB_WR_Reg(0x60, 0x80);
   SCCB_WR_Reg(0x61, 0x80);
   break;  
  case 3://偏红
   SCCB_WR_Reg(0xa6, 0x1e);
   SCCB_WR_Reg(0x60, 0x80);
   SCCB_WR_Reg(0x61, 0xc0);  
   break;
  case 4://偏绿
   SCCB_WR_Reg(0xa6, 0x1e);
   SCCB_WR_Reg(0x60, 0x60);
   SCCB_WR_Reg(0x61, 0x60);  
   break;
  case 5://偏蓝
   SCCB_WR_Reg(0xa6, 0x1e);
   SCCB_WR_Reg(0x60, 0xa0);
   SCCB_WR_Reg(0x61, 0x40); 
   break;
  case 6://复古
   SCCB_WR_Reg(0xa6, 0x1e);
   SCCB_WR_Reg(0x60, 0x40);
   SCCB_WR_Reg(0x61, 0xa0);
   break; 
 }

//设置图像输出窗口
//width:输出图像宽度,<=320
//height:输出图像高度,<=240
//mode:0,QVGA输出模式;1,VGA输出模式
//QVGA模式可视范围广但近物不是很清晰,VGA模式可视范围小近物清晰
void OV7725_Window_Set(u16 width,u16 height,u8 mode)
{
 u8 raw,temp;
 u16 sx,sy;
 
 if(mode)
 {
  sx=(640-width)/2;
  sy=(480-height)/2;
  SCCB_WR_Reg(COM7,0x06);  //设置为VGA模式
  SCCB_WR_Reg(HSTART,0x23);  //水平起始位置
  SCCB_WR_Reg(HSIZE,0xA0);  //水平尺寸
  SCCB_WR_Reg(VSTRT,0x07);  //垂直起始位置
  SCCB_WR_Reg(VSIZE,0xF0);  //垂直尺寸
  SCCB_WR_Reg(HREF,0x00);
  SCCB_WR_Reg(HOutSize,0xA0); //输出尺寸
  SCCB_WR_Reg(VOutSize,0xF0); //输出尺寸
 }
 else
 {
  sx=(320-width)/2;
  sy=(240-height)/2;
  SCCB_WR_Reg(COM7,0x46);  //设置为QVGA模式
  SCCB_WR_Reg(HSTART,0x3f);  //水平起始位置
  SCCB_WR_Reg(HSIZE, 0x50);  //水平尺寸
  SCCB_WR_Reg(VSTRT, 0x03);  //垂直起始位置
  SCCB_WR_Reg(VSIZE, 0x78);  //垂直尺寸
  SCCB_WR_Reg(HREF,  0x00);
  SCCB_WR_Reg(HOutSize,0x50); //输出尺寸
  SCCB_WR_Reg(VOutSize,0x78); //输出尺寸
 }
 raw=SCCB_RD_Reg(HSTART);
 temp=raw+(sx>>2);//sx高8位存在HSTART,低2位存在HREF[5:4]
 SCCB_WR_Reg(HSTART,temp);
 SCCB_WR_Reg(HSIZE,width>>2);//width高8位存在HSIZE,低2位存在HREF[1:0]
 
 raw=SCCB_RD_Reg(VSTRT);
 temp=raw+(sy>>1);//sy高8位存在VSTRT,低1位存在HREF[6]
 SCCB_WR_Reg(VSTRT,temp);
 SCCB_WR_Reg(VSIZE,height>>1);//height高8位存在VSIZE,低1位存在HREF[2]
 
 raw=SCCB_RD_Reg(HREF);
 temp=((sy&0x01)<<6)|((sx&0x03)<<4)|((height&0x01)<<2)|(width&0x03)|raw;
 SCCB_WR_Reg(HREF,temp);
 
 SCCB_WR_Reg(HOutSize,width>>2);
 SCCB_WR_Reg(VOutSize,height>>1);
 
 SCCB_RD_Reg(EXHCH); 
 temp = (raw|(width&0x03)|((height&0x01)<<2)); 
 SCCB_WR_Reg(EXHCH,temp); 
}
u16 Array[60] ={
  /*采集像素点矩阵【(46,150),(49,154)】 320列*/
 14870,14871,14872,14873,14874,
 15190,15191,15192,15193,15194,
 15510,15511,15512,15513,15514,
 15830,15831,15832,15833,15834,
  /*采集像素点矩阵【(100,10),(104,13)】 320列*/
 32010,32011,32012,32013,   
 32330,32331,32332,32333,
 32650,32651,32652,32653,
 32970,32971,32972,32973,
 33290,33291,33292,33293,
 /*采集像素点矩阵【(165,150),(168,154)】 320列  */
 52950,52951,52952,52953,52954,  
 53270,53271,53272,53273,53274,
 53590,53591,53592,53593,53594,
 53910,53911,53912,53913,53914,
};
void camera_refresh()
{
// u8 lightmode=0,saturation=2,contrast=2;
// u8 effect=0; 
//  u8 i=0;    
// u8 msgbuf[15];    //消息缓存区
// u8 tm=0;
// int r,tt;
 u32 j;
 u8 k = 0;
  u16 color;

 u8 whitepoint = 0;
 u8 leftblackpoint  = 0;
 u8 rightblackpoint = 0;
 u8 JudgeFlag = 0;
 
 u8 i=0;
 delay_init();       //延时函数初始化  
  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 
  POINT_COLOR=RED;   //设置字体为红色
  LCD_ShowString(30,0,200,16,16,"OPEN OV7670");  
 while(OV7725_Init())//初始化OV7670
 {
  LCD_ShowString(30,210,200,16,16,"OV7725 Error1!!");
  LCD_Fill(0,0,320,240,WHITE);
 }
  LCD_ShowString(30,17,200,16,16,"OV7725 Init OK");
 delay_ms(500);     
 OV7725_Light_Mode(lightmode);
 OV7725_Color_Saturation(saturation);
 OV7725_Contrast(contrast);
  OV7725_Special_Effects(effect);    
 TIM6_Int_Init(10000,7199);   //10Khz计数频率,1秒钟中断          
 EXTI8_Init();      //使能定时器捕获 
 OV7725_Window_Set(320,240,0); //1为VGA模式输出
//OV7725_Window_Set(OV7725_WINDOW_WIDTH,OV7725_WINDOW_HEIGHT,0);//0为QVGA模式输出 
  OV7725_CS=0;   
  LCD_Display_Dir(0); 
  while(1)
 { 
if(ov_sta)//有帧中断更新
 {
  LCD_Scan_Dir(U2D_L2R);  //从上到下,从左到右
  LCD_Set_Window((lcddev.width-320)/2,(lcddev.height-240)/2,320,240);//将显示区域设置到屏幕中央
  if(lcddev.id==0X1963)
   LCD_Set_Window((lcddev.width-320)/2,(lcddev.height-240)/2,240,320);//将显示区域设置到屏幕中央
  LCD_WriteRAM_Prepare();     //开始写入GRAM 
  OV7725_RRST=0;    //开始复位读指针
  OV7725_RCK_L;
  OV7725_RCK_H;
  OV7725_RCK_L;
  OV7725_RRST=1;    //复位读指针结束
  OV7725_RCK_H;
  for(i=0;i<240;i++)
  {
   for(j=0;j<320;j++)
   {
//    GPIOB->CRL=0X88888888;
//   OV7725_RCK_L;
//   color=GPIOB->IDR&0x00FF; //读数据
//   OV7725_RCK_H;
//   color<<=8; 
//   OV7725_RCK_L;
//   color|=GPIOB->IDR&0x00FF; //读数据
//   OV7725_RCK_H;
//   GPIOB->CRL=0X33333333; 
   LCD_WR_DATA(color);
//LCD->LCD_RAM=color;    
    OV7725_RCK_L;
    color=GPIOC->IDR&0XFF; //读数据
    OV7725_RCK_H;
    color<<=8; 
    OV7725_RCK_L;
    color|=GPIOC->IDR&0XFF; //读数据
    OV7725_RCK_H;
    gm_red = color>>11;
    gm_green = (color&0x07E0)>>5;
    gm_blue = (color&0x001F);
    if((gm_red<0X0008)&&(gm_blue<0X0020)&&(gm_green<0X0020))
     {    
      color =0x0000;    
     }
     else
     {   
       color=0xffff;
     } 
     LCD->LCD_RAM=color; 
   }
  }
   
  if(j == Array[k]&&(k<=60))//init(k) = 0           -=
   {
    if(k < 20)
    {
       
      if(!(color&0x8000))  //检测底片  黑,如果bit15为0,则黑点
      leftblackpoint++;
      
    }
    else if(k < 40)
    {
     if(color&0x8000)
     whitepoint++;  //测得白点
     
    }
    else if(k < 60)
    {
      if(!(color&0x8000))  //检测底片  黑,如果bit15为0,则黑点
      rightblackpoint++;
     
    }                  
   k++;
   }  
     }   
   ov_sta=0;     //开始下一次采集
   ov_frame++;
//  LCD_Scan_Dir(DFT_SCAN_DIR); //恢复默认扫描方向
  k=0;
  if(whitepoint<=13)     //中间端未检测到白色则停止
 {
//  JudgeFlag = 0;// stop
  GPIO_SetBits(GPIOE,GPIO_Pin_5);//红亮
  GPIO_SetBits(GPIOB,GPIO_Pin_5);//红灭
 }
  else
 {
  if((whitepoint>13)&&(leftblackpoint>13)&&(rightblackpoint>13))//如果左端块黑色  中端块白色 右端块黑色 则前进
  {
//   JudgeFlag = 1;
   GPIO_ResetBits(GPIOB,GPIO_Pin_5);//红亮
   GPIO_ResetBits(GPIOE,GPIO_Pin_5);//红亮
  }
 
  if(leftblackpoint <= 13 && rightblackpoint >13) //左端白色 右端黑色 则向往右
  {
//   JudgeFlag = 2;  //rihgt
   GPIO_ResetBits(GPIOE,GPIO_Pin_5);//红亮
  }
  if(leftblackpoint > 13 && rightblackpoint <= 13) //右端白色 左端黑色 则向往左
  {
//   JudgeFlag = 3;  //left
   GPIO_ResetBits(GPIOB,GPIO_Pin_5);//红亮
  }
    } 

 }
//return JudgeFlag; 
//   GPIO_ResetBits(GPIOB,GPIO_Pin_5);//红亮
//  ov_sta=0;     //清零帧中断标记
//  ov_frame++;
  LCD_Scan_Dir(DFT_SCAN_DIR); //恢复默认扫描方向
 }
  
 












评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

当黄昏靠岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值