本帖最后由 维博哥哥 于 2016-9-12 18:54 编辑
- #include <Wire.h>
- #include <OV7670.h>
- int PinD7 = 53;
- int PinD6 = 52;
- int PinD5 = 51;
- int PinD4 = 50;
- int PinD3 = 49;
- int PinD2 = 48;
- int PinD1 = 47;
- int PinD0 = 46;
- int WRST = 45;
- int RRST = 43;
- int OE = 41;
- int RCLK = 44;
- int WEN = 42;
- int VSY = 40;
- int led = 13;
- OV7670 cam;
- unsigned int temp1;
- int flag;
- unsigned char cur_status=0;
- volatile int state = LOW;
-
- void setup() {
- Serial.begin(9600);
- Wire.begin();
-
- pinMode(PinD7,INPUT_PULLUP);
- pinMode(PinD6,INPUT_PULLUP);
- pinMode(PinD5,INPUT_PULLUP);
- pinMode(PinD4,INPUT_PULLUP);
- pinMode(PinD3,INPUT_PULLUP);
- pinMode(PinD2,INPUT_PULLUP);
- pinMode(PinD1,INPUT_PULLUP);
- pinMode(PinD0,INPUT_PULLUP);
-
- pinMode(WRST,OUTPUT);
- pinMode(RRST,OUTPUT);
- pinMode(OE,OUTPUT);
- pinMode(RCLK,OUTPUT);
- pinMode(WEN,OUTPUT);
-
- pinMode(led,OUTPUT);
-
-
- cam.init();
- digitalWrite(OE,LOW);
- attachInterrupt(VSY, stateChange, CHANGE);
- }
- void loop() {
- int i,j;
- cam.readpid();
- Serial.println("*****************");
- Serial.println((int)cam.pid);
- Serial.println("*****************");
-
-
- if(cur_status == 2)
- {
-
- digitalWrite(RRST,LOW);
- digitalWrite(RCLK,LOW);
- digitalWrite(RCLK,HIGH);
- digitalWrite(RCLK,LOW);
- digitalWrite(RRST,HIGH);
- digitalWrite(RCLK,HIGH);
- for(i=0;i<240;i++)
- {
- Serial.print(i);
- Serial.println(" ");
- for(j=0;j<320;j++)
- {
- digitalWrite(RCLK,LOW);
- temp1 = Read();
- digitalWrite(RCLK,HIGH);
- flag = temp1>>7;
- temp1 <<= 8;
- digitalWrite(RCLK,LOW);
- temp1 |= Read();
- digitalWrite(RCLK,HIGH);
-
- //Serial.print(temp1,HEX);
- Serial.print(flag);
- Serial.print(" ");
- }
- Serial.println("");
- }
- while(1);
- }
- delay(1000);
- }
- uint8_t Read(void)
- {
- uint8_t tmp;
- tmp = 0;
- tmp |= (digitalRead(PinD0) << 0);
- tmp |= (digitalRead(PinD1) << 1);
- tmp |= (digitalRead(PinD2) << 2);
- tmp |= (digitalRead(PinD3) << 3);
- tmp |= (digitalRead(PinD4) << 4);
- tmp |= (digitalRead(PinD5) << 5);
- tmp |= (digitalRead(PinD6) << 6);
- tmp |= (digitalRead(PinD7) << 7);
-
- return tmp;
- }
- void stateChange()
- {
- if(cur_status==0) //如果此时状态为0,则说明是一个图像的开始,开始向FIFO罐入数据
- {
- digitalWrite(WRST,LOW);// FIFO_WRST=0;
- digitalWrite(WRST,HIGH);//FIFO_WRST=1;
- digitalWrite(WEN,HIGH);//FIFO_WEN=1;
- cur_status=1; //标记为1
- }
- else
- if(cur_status==1) //说明此处为图像的结束,亦即下一图像的开始
- {
- digitalWrite(WEN,LOW);// FIFO_WEN=0;
- digitalWrite(WRST,LOW);//FIFO_WRST=0;
- digitalWrite(WRST,HIGH);//FIFO_WRST=1;
- cur_status=2;
- state = !state;
- digitalWrite(led,HIGH);
- }
- }
复制代码OV7670是Omni公司的一款30W像素的摄像头,在单片机摄像头里边属于入门级的了。一般的有两种,带fifo缓存芯片的和不带的。我刚用的时候也犯过这种错误,以为不带的fifo只需要单片机读的速度快一点就行。但事实上,没有fifo芯片的ov7670还没有晶振,一般只用做那种开发板给它振动频率,然后直接显示在液晶屏上,不做任何处理。
网上关于OV7670的资料很多,但是用arduino驱动的很少,之前在arduino.cc看有国外的人写过驱动,但不是用arduino的软件编译,不是很懂。再有就是没有接线图,让一般人摸不着头脑。
我之前也写过一篇关于arduino读OV7670的寄存器的帖子,但那比较简单。这次我直接给arduino DUE写了一个库,设置几乎绝大多数寄存器,这个成功让我很有成就感。
但是,限于我对图片保存的知识的欠缺,我只能将读到的图像数据,通过串口转化成二值矩阵,复制成一个文本文件,用Matlab显示出来。
摄像头的接线,按照代码里就行,我用DUE直接I2C读这个SCCB协议的数据。设置的图片240*360,所以最后在串口助手中显示得很大。 |