Last active
May 27, 2019 13:47
-
-
Save Near32/225cdca19ad55c6d8306 to your computer and use it in GitHub Desktop.
OV7670 + ARDUINO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define SIO_C 2 | |
#define SIO_D 4 | |
#define SIO_CLKDELAY 100 | |
void setup (void) | |
{ | |
Serial.begin(9600); | |
if(InitOV7670()) | |
Serial.println("Init OV7670 : OK"); | |
else | |
Serial.println("Init OV7670 : NG...."); | |
} | |
void loop( void) | |
{ | |
Serial.println("Writing test :"); | |
byte data = 0x84; | |
Serial.println(data); | |
if(WriteOV7670(0x12, data)) | |
Serial.println("Writing : OK"); | |
else | |
Serial.println("Writing : NG..."); | |
/*--------------------------*/ | |
Serial.println("\n Reading test :"); | |
char rdata = 0x20; | |
char ip = 0x43; | |
if(ReadOV7670(0x0A, &rdata, ip)) | |
{ | |
Serial.println("Reading : OK "); | |
} | |
else | |
Serial.println("Reading : NG..."); | |
Serial.println(rdata, HEX); | |
if(rdata == 0x76) | |
Serial.println("youpi"); | |
/*-----------------------------*/ | |
int temp = 3600; | |
delay(temp*1000); | |
} | |
void InitSCCB(void) | |
{ | |
pinMode(SIO_C, OUTPUT); | |
pinMode(SIO_D, OUTPUT); | |
digitalWrite(SIO_C, HIGH); | |
digitalWrite(SIO_D, HIGH); | |
Serial.println("InitSCCB - Port Direction and set high."); | |
} | |
void StartSCCB(void) | |
{ | |
Serial.println("Starting SCCB..."); | |
/*put HIGH in order to avoid propagating unknown bus state.*/ | |
digitalWrite(SIO_D, HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_D, LOW); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, LOW); | |
Serial.println("Starting SCCB : done."); | |
} | |
void StopSCCB(void) | |
{ | |
Serial.println("Stoping SCCB..."); | |
digitalWrite(SIO_D,LOW); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C,HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_D,HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
Serial.println("Stoping SCCB : done."); | |
} | |
char WriteSCCB( byte m_data) | |
{ | |
unsigned char j, tem; | |
for(j=0;j<8;j++) | |
{ | |
/*write the MSB not written yet :*/ | |
if((m_data<<j)&0x80) | |
{ | |
digitalWrite(SIO_D, HIGH); | |
} | |
else | |
{ | |
digitalWrite(SIO_D, LOW); | |
} | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, LOW); | |
delayMicroseconds(SIO_CLKDELAY); | |
} | |
/*eight bits have been send, let's deal with the ninth Don't-care one*/ | |
/*we put the SIO_D pin at low in order to avoid propagating any unknown state.*/ | |
/*why input ? because it enables a high impedance, I suppose...?*/ | |
pinMode(SIO_D, INPUT); | |
digitalWrite(SIO_D, LOW); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
/*there is something to read to check the transmission :*/ | |
if(digitalRead(SIO_D)==HIGH) | |
{ | |
Serial.println("SCCB Write NG"); | |
tem = 0; | |
} | |
else | |
{ | |
tem = 1; | |
Serial.println("SCCB Write : OK."); | |
} | |
digitalWrite(SIO_C, LOW); | |
delayMicroseconds(SIO_CLKDELAY); | |
/*let's clean that up :*/ | |
pinMode(SIO_D, OUTPUT); | |
return tem; | |
} | |
char ReadSCCB( char* m_data) | |
{ | |
unsigned char j, tem = 1; | |
/*we have to return tem but there is no way to assert that something/nothing happend apparently ?...*/ | |
/*Let's make things readable :*/ | |
//pinMode(SIO_D, INPUT); | |
digitalWrite(SIO_D, LOW); | |
/*Hi-Z*//*TEST*/ | |
for(j=0;j<8;j++) | |
{ | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, HIGH); | |
/*let's read in the middle of the SIO_C cycle :*/ | |
/*read the MSB not read yet :*/ | |
if(digitalRead(SIO_D) != LOW) | |
{ | |
*m_data = 0x01 | (*m_data << 1); | |
} | |
else | |
{ | |
*m_data = 0xFE & (*m_data << 1) ; | |
} | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, LOW); | |
delayMicroseconds(SIO_CLKDELAY); | |
} | |
/*eight bits have been read, let's deal with the ninth Don't-care one*/ | |
/*the master is responsible for driver SIO_D at logical 1 during the NA bit.*/ | |
pinMode(SIO_D, OUTPUT); | |
digitalWrite(SIO_D, HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
digitalWrite(SIO_C, HIGH); | |
delayMicroseconds(SIO_CLKDELAY); | |
/*there is something/nothing to read to check the transmission ???*/ | |
digitalWrite(SIO_C, LOW); | |
delayMicroseconds(SIO_CLKDELAY); | |
/*let's clean that up : reset as usual as if we had written...*/ | |
pinMode(SIO_D, OUTPUT); | |
digitalWrite(SIO_D, LOW); | |
return tem; | |
} | |
int WriteOV7670(char regID, char regData) | |
{ | |
StartSCCB(); | |
/*let's indicate that we want to write :*/ | |
if(WriteSCCB(0x42) == 0) | |
{ | |
Serial.println("Problem : 3phase Write Error 0x42 phase 1."); | |
StopSCCB(); | |
return(0); | |
} | |
delayMicroseconds(SIO_CLKDELAY); | |
/*phase 2 : sub address*/ | |
if(WriteSCCB(regID) == 0) | |
{ | |
Serial.println("Problem : 3phase Write Error phase 2."); | |
StopSCCB(); | |
return(0); | |
} | |
delayMicroseconds(SIO_CLKDELAY); | |
/*phase 3 : data writing*/ | |
if(WriteSCCB(regData) == 0) | |
{ | |
Serial.println("Problem : 3phase Write Error phase 3."); | |
StopSCCB(); | |
return(0); | |
} | |
/*exiting*/ | |
StopSCCB(); | |
return(1); | |
} | |
int ReadOV7670(char regID, char* regData, char ip) | |
{ | |
StartSCCB(); | |
/*2-phase write transmission cycle */ | |
/*---------------------------------*/ | |
/*let's indicate that we want to write :*/ | |
if(WriteSCCB(0x42) == 0) | |
{ | |
Serial.println("Problem : 2phase Write Error 0x42 phase 1-1."); | |
StopSCCB(); | |
return(0); | |
} | |
delayMicroseconds(SIO_CLKDELAY); | |
/*phase 2 : sub-address*/ | |
if(WriteSCCB(regID) == 0) | |
{ | |
Serial.println("Problem : 2phase Write Error phase 1-2."); | |
StopSCCB(); | |
return(0); | |
} | |
delayMicroseconds(SIO_CLKDELAY); | |
/*---------------------------------*/ | |
/*2-phase read transmission cycle*/ | |
/*phase 1 : ID address*/ | |
if(WriteSCCB(ip) == 0)/*test 0x21 instead of 0x43*/ | |
{ | |
Serial.println("Problem : 2phase Read Error phase 2-1."); | |
StopSCCB(); | |
return(0); | |
} | |
delayMicroseconds(SIO_CLKDELAY); | |
/*phase 2 : data reading*/ | |
if(ReadSCCB(regData) == 0) | |
{ | |
Serial.println("Problem : 2phase Read Error phase 2-2."); | |
StopSCCB(); | |
return(0); | |
} | |
/*exiting*/ | |
StopSCCB(); | |
return(1); | |
} | |
int InitOV7670(void) | |
{ | |
char temp; | |
int i = 0; | |
InitSCCB(); | |
temp = 0x80; | |
/*let's reset the SCCB ! */ | |
if( WriteOV7670( 0x12, temp) == 0) | |
{ | |
Serial.println("Problem : Resetting SCCB NG."); | |
return(0); | |
} | |
/*-------------*/ | |
/*settings : */ | |
/*-------------*/ | |
return(0x01); | |
} |
hello
don't forget to uncomment line 181 to get good results
good luck
Hi I'm having a lot of difficulty getting the ov7670 working I've got to Problem : 2phase Read Error phase 2-1. How do I set the xclck fuse and how do I output the image please help
hello all, can you help me on OV7670 camera interface with Arduino?
can anyone provide connection diagram??
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In order to solve the "Problem: 2phase Read Error phase 2-1" you need to drive a clock signal to the XCLK of the camera module. I did it by fusing the CKOUT of my AVR.