OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11042|回复: 13

摄像头问题

[复制链接]

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
发表于 2013-8-1 21:11:49 | 显示全部楼层 |阅读模式
在摄像头例程里,如果修改 
void camera_refresh(void)里面的 if(ov_sta==2)所含有的全局变量,虽然硬件仿真显示已经修改,但是实际上并没有修改。大家可以试试。
定义一个全局变量 u8 tt=0; 在if(ov_sta==2)里面修改 tt=5;
然后在main函数中调用这个变量 显示LCD_ShowxNum(156,130,tt,4,16,0);
会发现tt一直都是0.大家也可以用串口试试。
这个问题我已经困扰好久了,可以看2楼这个帖子。希望大家关注下,解救下我这个菜鸟。因为我要采集camera_refresh()里面的值,结果一直是0.郁闷





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-1 21:12:08 | 显示全部楼层
http://www.openedv.com/posts/list/18957.htm
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2013-8-1 22:10:42 | 显示全部楼层
我在camera_refresh(void)中定义的tt是有返回值的哦~程序贴上来看看
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-1 22:23:59 | 显示全部楼层
回复【3楼】745021926:
---------------------------------
程序太长了。贴上来你们未必肯看。不知道你的结果怎么样。如果在camera_refresh()里面定义的话,貌似是可以
实现的。麻烦你在外面定义一下,然后尝试一下能不能改变他的值。
下面上程序。
回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-1 22:25:19 | 显示全部楼层
#include "sys.h"
#include "usart.h"
#include "delay.h"    
#include "exti.h"
#include "timer.h"    
#include "lcd.h"    
#include "ov7670.h"
u8 tt=5; 
typedef struct  
{     
s8 l;
s8 r;
s8 m;  
}V_seek;
V_seek vseek[80];
extern u8 ov_sta; //在exit.c里面定义
u8 pix[60][80],gap=2,distance=10,D_value=5;   
   
//更新LCD显示
void camera_refresh(void)
{
u32 i,j;
u8 aa,bb,cc,dd;
  u16 color;
//tt=55; 
if(ov_sta==2)
{
tt=55;   //这里做了修改
aa=0;
bb=0;
cc=0;
dd=0;
LCD_WriteReg(0x0050,0); 
LCD_WriteReg(0x0051,59); //x
LCD_WriteReg(0x0052,0); 
LCD_WriteReg(0x0053,79); //y
LCD_Scan_Dir(U2D_L2R); //从上到下,从左到右 
LCD_SetCursor(0,0); //设置光标位置 
LCD_WriteRAM_Prepare();     //开始写入GRAM
OV7670_RRST=0; //开始复位读指针 
OV7670_RCK=0;
OV7670_RCK=1;
OV7670_RCK=0;
OV7670_RRST=1; //复位读指针结束 
OV7670_RCK=1;
for(i=0;i<60;i++)
{
for(j=0;j<80;j++) //读取图像数据
{
OV7670_RCK=0;
color=OV7670_DATA; //读数据
OV7670_RCK=1; 
color<<=8;  
OV7670_RCK=0;
color|=OV7670_DATA; //读数据
OV7670_RCK=1;
  pix[j]=color >>11; //0~31
// pix[j]=pix[j]/16*16;
LCD->LCD_RAM=(pix[j]<<11)|(pix[j]<<6)|pix[j];
// LCD->LCD_RAM=color;
OV7670_RCK=0;
OV7670_RCK=1; 
OV7670_RCK=0;
OV7670_RCK=1;
}

}
LCD_WriteReg(0x0050,120);   
LCD_WriteReg(0x0051,179);   //x
LCD_WriteReg(0x0052,0); 
LCD_WriteReg(0x0053,79); //y
LCD_Scan_Dir(L2R_D2U); //从左到右,从下到上
LCD_SetCursor(120,79); //设置光标位置  
LCD_WriteRAM_Prepare();     //开始写入GRAM
for(j=80;j>0;j--) //输出图像数据
{
aa=0;
bb=0;
cc=0;
for(i=0;i<60;i++)
if(i>gap)
{
if(pix[j]-pix[i-gap][j]>D_value) vseek[j].l=i; //左边沿
if(pix[i-gap][j]-pix[j]>D_value) vseek[j].r=i; //右边沿
if(vseek[j].l-vseek[j].r<distance) vseek[j].m=(vseek[j].l+vseek[j].r)/2;
}
for(i=0;i<60;i++)
{


if(i==vseek[j].l&&aa==0)  //左边沿
{
LCD->LCD_RAM=BLUE;
aa=1;
}  
else if(i==vseek[j].m&&bb==0) //中值
{
LCD->LCD_RAM=GREEN;
bb=1;

else if(i==vseek[j].r&&cc==0) //右边沿
{
cc=1;
LCD->LCD_RAM=RED;
}
else
LCD->LCD_RAM=WHITE;
}
}     
EXTI->R=1<<0;      //清除LINE0上的中断标志位
ov_sta=0; //开始下一次采集
LCD_Scan_Dir(DFT_SCAN_DIR); //恢复默认扫描方向
}  
}
 
int main(void)
{
u8 lightmode=0,saturation=2,brightness=0,contrast=4,effect=0;       
  Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,9600);   //串口初始化为9600
delay_init(72);       //延时初始化 
   OV7670_Init();
TIM4_PWM_Init(7199,0);
LCD_Init();     //初始化LCD     
  POINT_COLOR=RED;//设置字体为红色   
   LCD_ShowString(60,230,200,16,16,"OV7670 Init...");
while(OV7670_Init())//初始化OV7670
{
LCD_ShowString(60,230,200,16,16,"OV7670 Error!!");
delay_ms(200);
    LCD_Fill(60,230,239,246,WHITE);
delay_ms(200);
}
  LCD_ShowString(60,230,200,16,16,"OV7670 Init OK");
delay_ms(1500);      
OV7670_Light_Mode(lightmode);
OV7670_Color_Saturation(saturation);
OV7670_Brightness(brightness);
OV7670_Contrast(contrast);
  OV7670_Special_Effects(effect);     
EXTI0_Init(); //使能外部中断捕获
   OV7670_CS=0;    
  while(1)
{
camera_refresh();
LCD_ShowxNum(156,130,tt,4,16,0);

}           
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-1 22:25:40 | 显示全部楼层
回复【楼主位】zcd1992:
---------------------------------
加violate关键字试试。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-1 22:36:07 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
回复【3楼】745021926:
---------------------------------
加了关键字 volatile 还是没用
回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-1 23:09:45 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
电脑好像用不了串口,例程也下不去。。我用 if语句可以知道这个输出值一直是0
回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-2 00:33:24 | 显示全部楼层
我在修改那里标志了,四楼标记了
回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-2 00:35:40 | 显示全部楼层
如果这样子不行的,想问下大家是怎么提取像素点分析的。。我提取的变量根本跑不出那个IF语句。。
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2013-8-2 10:00:02 | 显示全部楼层
//更新LCD显示,数据处理
void camera_refresh(void)
{
u32 j; //循环采样76800像素点
  u16 color,last_color;//像素点数据  
u16 R,G,B; //RGB三基色
u8 x,y;  //x,y坐标
// u8 Left_Frame_y[240];//图像左边框像素点的y坐标
u16 Left_Frame_x[240];//图像左边框像素点的x坐 标

if(ov_sta==2)
{

a++;
LCD_Scan_Dir(U2D_L2R); //从上到下,从左到右 
LCD_SetCursor(0x00,0x0000); //设置光标位置 
LCD_WriteRAM_Prepare();     //开始写入GRAM
  OV7670_CS=0;  
  OV7670_RRST=0; //开始复位读指针 
OV7670_RCK=0;
OV7670_RCK=1;
OV7670_RCK=0;
OV7670_RRST=1; //复位读指针结束 
OV7670_RCK=1;  
Xmin=320;   //对最小值复位
Xmax=0;  //对最大值复位
for(j=0;j<76800;j++)
{
OV7670_RCK=0; 
color=OV7670_DATA; //读数据
OV7670_RCK=1; 
color<<=8;   
  OV7670_RCK=0;
color|=OV7670_DATA; //读数据
OV7670_RCK=1;   

R=color>>11;
G=(color&0x07E0)>>5;
B=(color&0x001F);
x=j%320;   //求x,y坐标
y=j/320;
// if(Judge_Green) color=GREEN; //检测绿色
// if(Judge_Red)   color=RED; //检测红色
// if(Judge_Blue)  color=BLUE; //检测蓝色
// else color=WHITE;  //白色
if((R<0X0015)&&(B<0X0015)&&(G<0X0015)) color=0x0000; //检测黑色
else color=WHITE;  //白色
     if((last_color==WHITE)&&(color==BLACK))//检测图像最左边的边框像素点
{
if (Left_Frame_x[y]==0)
{
Left_Frame_x[y]=x; //储存每一行的左边框处x坐标
color=RED;
if(Xmax<Left_Frame_x[y]) Xmax=Left_Frame_x[y];//求出x最大值
if(Xmin>Left_Frame_x[y]) Xmin=Left_Frame_x[y];//求出x最小值
    }
}

     // printf("R=%d   G=%d   B=%d  \n",R,G,B); //打印出三基色   
 
LCD_WR_DATA(color);  //LCD写点
last_color=color;    //记下显示过的一个像素点


  OV7670_CS=1;   
OV7670_RCK=0; 
OV7670_RCK=1; 
EXTI->R=1<<10;      //清除LINE8上的中断标志位
ov_sta=0; //开始下一次采集
  ov_frame++; 
// LCD_Scan_Dir(DFT_SCAN_DIR); //恢复默认扫描方向        
}
//此处一帧图像写完,下面为数据处理部分
////////////////////算法部分//////////////////////////// 
/*   if((Xmax!=0))
  {
   printf("Xmax=%d Xmin=%d\n",Xmax,Xmin); //打印出左边框x,y坐标最大值,最小值
  }   */
  buffer[0]=Left_Frame_x[30];
  buffer[1]=Left_Frame_x[60];
  buffer[2]=Left_Frame_x[90];
  buffer[3]=Left_Frame_x[120];
  buffer[4]=Left_Frame_x[150];
  buffer[5]=Left_Frame_x[180];
  buffer[6]=Left_Frame_x[211];
  tt= judge(buffer);
  memset(Left_Frame_x,0,480) ;// 清除Left_Frame_x数组的空间
 /* switch (tt)
  {
   case 1CD_ShowString(60,150,200,200,16,"Square");break;
   case 2CD_ShowString(60,150,200,200,16,"Triangle");break;
case 3CD_ShowString(60,150,200,200,16,"Cross");break;
case 4CD_ShowString(60,150,200,200,16,"Circle");break;
default:break; 
  } */
//  printf("Image=%d\n",tt);
/*    printf("X[30]=%d\n",Left_Frame_x[30]); //打印出左边框30行的x坐标
printf("X[60]=%d\n",Left_Frame_x[60]); //打印出左边框30行的x坐标
printf("X[90]=%d\n",Left_Frame_x[90]); //打印出左边框30行的x坐标
printf("X[120]=%d\n",Left_Frame_x[120]); //打印出左边框30行的x坐标
printf("X[150]=%d\n",Left_Frame_x[150]); //打印出左边框30行的x坐标
printf("X[180]=%d\n",Left_Frame_x[180]); //打印出左边框30行的x坐标
printf("X[211]=%d\n",Left_Frame_x[211]); //打印出左边框30行的x坐标     */

}

u8  judge(u16 acqure[])
{
     u8 index=0;
 int buf[6]=0;
 u8 zheng=0,sanjiao=0;
     for(index=0;index<6;index++)
{
  buf[index]=acqure[index+1]-acqure[index];
   if((abs(buf[index])<8))
    zheng++;
 if((buf[index]<25)&&(buf[index]>0))    //OK
          sanjiao++;
}
/*   printf("b0=%d\n",buf[0]);
  printf("b1=%d\n",buf[1]);
  printf("b2=%d\n",buf[2]);
  printf("b3=%d\n",buf[3]);
  printf("b4=%d\n",buf[4]);
  printf("b5=%d\n",buf[5]); */
if(zheng>4)
return 1;   //正方形
if(sanjiao>4)
return 2;   //三角形
   if((buf[0]<10)&&(buf[5]<10)&&(buf[2]<-70)||(buf[0]<10)&&(buf[5]<10)&&(buf[4]>70))
return 3;   //十字架
if((buf[0]<0)&&(buf[1]<0)&&(buf[2]<0)&&(buf[3]>0)&&(buf[4]>0)&&(buf[5]>0)&&(abs (buf[1]))<40&&(abs (buf[4]))<40)
return 4;     //圆形   
}
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2013-8-2 10:04:46 | 显示全部楼层
我也是在最上面定义的tt,有返回值的,也实现了基本识别。

你说程序下不进去的话看看是不是硬件问题什么的,看下SCCB,LCD,OV7670初始化函数中有没有禁止JTAG和SWD

串口不能用的话看下引脚定义有没有冲突了...    还有中断优先级有没有冲突
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2013-8-2 10:06:57 | 显示全部楼层
我的算法只是粗糙地提取了图像的左边框几个像素点,然后根据特征进行的识别,你看下我是怎么求x,y坐标,怎么求左边框像素点位置的,我觉得你写的复杂了
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2013-3-31
在线时间
3 小时
 楼主| 发表于 2013-8-2 13:09:27 | 显示全部楼层
回复【13楼】745021926:
---------------------------------
我找到原因了。。。LCD_ShowNum(132,150,MOUSE_ID,3,16);这个函数就可以正常显示了。。这么久原来是这个问题
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-15 21:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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