Implementation of SCCB bus based on OV7670 camera

Publisher:HeavenlyJoy444Latest update time:2019-11-12 Source: 51heiKeywords:OV7670 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The SCCB bus of OV7670, which made me miss it day and night, was finally solved today. I spent nearly 5 days on it. I thought about it on the way to work, when I was eating, when I was going to the toilet, and when I couldn't sleep at night. Except when I didn't think about it at night when playing DOTA, I almost always thought about this problem. SCCB is very similar to IIC bus. I did IIC bus as early as last year. It's not very difficult. The host sends a data packet and the slave responds. So I built a circuit board. The problem is that my MCU is 5V and the camera requires the power supply voltage and IO cannot exceed 3V. What should I do? I looked for the manual, and the manual said that the minimum operating voltage is 3.7V. No, the voltage is too high and it will burn it. I am at a loss. What should I do? It happened that I had a few AVR high-speed microcontrollers on hand, so I started using them, and finally the power supply voltage problem was solved. I thought it was not a big problem, as its operating voltage could reach 2.8V, so I connected it and started writing programs into it. But no matter how I adjusted it, it didn't work. No matter how I debugged, I couldn't read back the data. The data was the key to whether the handshake between the flag and OV7670 was successful. I used simulation methods to write the program, because it does not require a lot of hardware overhead, but it takes up a lot of CPU time, so I wondered if the timing was wrong at high speed or exceeded 400KHZ? It's possible, so I added a lot of delays, but not only was I disappointed, but I also got nonsense and no response. I was so worried, so I asked the seller for technical information, but he said he could only give me a data sheet and asked for extra money. I refused to do that, and then I looked for information on the Internet. They were all made with ARM, and most of their codes were based on LINUX, which was not universal at all. I couldn't understand them at this level, so after going around in circles, I finally came back to my own code. What exactly caused the problem? I didn't have an oscilloscope or logic analyzer, only a single-unit multimeter, which was very frustrating. I also didn't know what waveform the program was. After simulating it with software, there was definitely no problem with the timing, but I just read out the data, and the data was always wrong. My first turning point was to consider the power supply voltage, and I found a pattern: whenever I didn't connect the 0V7670, the data displayed on the PC was always correct, but as soon as I connected it, garbled characters appeared. Or was it an error? Was it interference? There is no high-frequency interference source. I still use the internal crystal oscillator, and the power supply has two filters. This information made me measure the VCC voltage of the MCU. The result is an amazing coincidence. When I don't connect the 7670, the power supply voltage is 2.8V, and the data is sent normally. Once connected, it becomes 2.6V, which has reached the threshold of the MCU's low voltage detection. The MCU is going to reset. Haha, the problem is found. The culprit is the power supply voltage, but I don't have a dedicated voltage regulator chip so I dare not connect the 3.3V voltage to VCC. Yesterday, I finally plucked up the courage to pick up the soldering iron, VCC=3.4V, and the MCU works normally. As for the 7670, I didn't know what state it was at that time, because the IO and VCC voltages were greater than the voltages in its manual. I wrote the program into it with my head held high. Every time I experimented, I was worried, but the result was still not good. I was so depressed! Why is it so fucked up? The second turning point: since simulation didn’t work, I used hardware and started to do it with hardware. I spent the whole morning reading the manual yesterday and learned how to set up and program registers. I debugged it yesterday afternoon and the experiment was successful this morning. The data was read out. It seems that 7670 is very demanding on handshakes! ! ! !


The following program


#include
#define uchar unsigned char 
#define uint unsigned int 
#define set_bit(a,b) a|=(1<#define clr_bit(a,b) a&=(1<#define get_bit(a,b) a&(1<#pragma interrupt_handler TX_end:14
uchar TXEND;
void TX_end()
{
TXEND=0;//Send completed flag
}
void USART_INT()//Initialize serial port
{
//UCSRA defaults to
UCSRB=0x48;//Enable send completed interrupt, disable data register empty interrupt, enable send mode, disable receive, disable receive interrupt
UCSRC=0x86;//Disable parity check, data bit 8, stop bit 1, work in asynchronous mode
UBRRH=0x00;//
UBRRL=51;//Baud rate 9600, 8MHZ,
SREG=0x80;//Enable global interrupt
}

void send_byte(uchar buffer)//Send data to PC
{
   while(0==get_bit(UCSRA,5));//Is the data in the data register empty? If so, write data
  
    UDR=buffer;


while(TXEND);//Is the sending completed?
TXEND=1;//The previous frame has been sent, prepare to send the next frame
}
/*void ov7670_int()//7670 initialization function
{

}*/


////***********SCCB-----OX7670************************///////////
void delay1ms(uint z)
{
uint j,k; 
    for(k=z;k;k--)
                       {                           
                      for(j=2666;j;j--); //Here j must not be less than 27, otherwise the data cannot be read
        }
                
}

void int_twi_sccb()
{
TWBR=50;//Set the clock frequency of SCL to 19.230khz
}
void send_model_sccb()//Master send mode program
{
    TWCR=0xa4;//Insert a new start number to enable the bus, enable START
send_byte(0xf4);
send_byte(0xcc);
send_byte(0xf4);
while(0==get_bit(TWCR,7));//Check if the start signal is sent?
while((TWSR&0xf8)!=0x08)
{send_byte(0xf4);
     send_byte(0x01);
     send_byte(0xf4);//Error
}
send_byte(0xf4);
send_byte(0x10);
send_byte(0xf4);//Correct response code of START signal


TWDR=0x42;//Write operation SCCB device write address 0X42
TWCR=0x84;//Restart the sending of start data
send_byte(0xf4);
send_byte(0xcc);
send_byte(0xf4);
while(0==get_bit(TWCR,7));//Check if the data signal is sent?
while((TWSR&0XF8)!=0x18)
{send_byte(0xf4);
send_byte(0x02);
send_byte(0xf4);
     }

send_byte(0xf4);
send_byte(0x20);
send_byte(0xf4);//Sending is completed with ACK response code


TWDR=0x0b;//Write operation SCCB register address 0x0a
TWCR=0x84;//Restart sending of start data
send_byte(0xf4);
send_byte(0xcc);
send_byte(0xf4);
while(0==get_bit(TWCR,7));//Check whether the data signal is sent?
while((TWSR&0XF8)!=0x28)
{
send_byte(0xf4);
send_byte(0x03);//Error
send_byte(0xf4);
     }

send_byte(0xf4);
send_byte(0x30);
send_byte(0xf4);//Sending completed with ACK response code


TWCR=0x94;//STOP signal





}
uchar incept_model_sccb()//Main receiving mode program
{
     uchar date;
TWCR=0xa4;//Insert a new start number to enable the bus, enable START
send_byte(0xf4);
send_byte(0xcc);
send_byte(0xf4);
while(0==get_bit(TWCR,7));//Check whether the start signal is sent?
while((TWSR&0XF8)!=0x08)
{send_byte(0xf4);
send_byte(0x04);//Error
send_byte(0xf4);
     }

send_byte(0xf4);
send_byte(0x40);
send_byte(0xf4);//Correct response code for START signal

TWDR=0x43;//Device write address 0X43 for write operation SCCB
TWCR=0x84;//Restart sending of start data
send_byte(0xf4);
send_byte(0xcc);
send_byte(0xf4);
while(0==get_bit(TWCR,7));//Check whether the data signal is sent?
while((TWSR&0XF8)!=0x40)
{send_byte(0xf4);
send_byte(0x05);//Error
send_byte(0xf4);
     }

send_byte(0xf4);
send_byte(0x50);
send_byte(0xf4);//Sending completed with ACK response code


TWCR=0x84;//Start receiving data
send_byte(0xf4);
send_byte(0xcc);
send_byte(0xf4);
while(0==get_bit(TWCR,7));//Check whether the data signal is sent?
date=TWDR;
while((TWSR&0XF8)!=0x58)
{send_byte(0xf4);
send_byte(0x06);
send_byte(0xf4);}//Error

send_byte(0xf4);
send_byte(0x60);
send_byte(0xf4);//Sending completed with NACK response code


TWCR=0x94;//STOP signal

return(date);
}

void main()
{
uchar inceptdate;
DDRC=0xff;
PORTC=0xff;
USART_INT();
int_twi_sccb();

send_model_sccb();
delay1ms(2);
inceptdate=incept_model_sccb();
send_byte(0xf4);
send_byte(inceptdate);
send_byte(0xf4);
while(1);

}

Keywords:OV7670 Reference address:Implementation of SCCB bus based on OV7670 camera

Previous article:8-bit common anode digital tube 74HC595 chip AVR microcontroller control proteus simulation and source code
Next article:AVR microcontroller water light and button anti-interference

Recommended ReadingLatest update time:2024-11-22 10:30

Video Performance and Dynamic Analysis of IP Camera Monitoring System
Modern people are paying more and more attention to personal and property safety, which has led to the rapid rise of the video security surveillance market. Based on the attention to this market and the development of digital signal processing technology (DSP) and network technology, video surveillance has developed
[Security Electronics]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号