- #include<iom16v.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define set_bit(a,b) a|=(1<<b)
- #define clr_bit(a,b) a&=(1<<b)
- #define get_bit(a,b) a&(1<<b)
- #pragma interrupt_handler TX_end:14
- uchar TXEND;
- void TX_end()
- {
- TXEND=0;//發送完畢標志
- }
- void USART_INT()//初始化串口
- {
- //UCSRA默認
- UCSRB=0x48;//使能發送完畢中斷,禁能數據寄存器空中斷,使能發送模式,關閉接收,關閉接收中斷
- UCSRC=0x86;//禁止奇偶效驗,數據位8,停止位1,工作在異步模式
- UBRRH=0x00;//
- UBRRL=51;//波特率9600,8MHZ,
- SREG=0x80;//開啟全局中斷
- }
-
- void send_byte(uchar buffer)//向PC發送數據
- {
- while(0==get_bit(UCSRA,5));//數據寄存器里的數據是不是為空如果是就寫數據
-
- UDR=buffer;
-
-
- while(TXEND);//是否發送完畢?
- TXEND=1;//上一幀已經發送準備下一幀的發送
- }
- /*void ov7670_int()//7670初始化函數
- {
-
- }*/
-
-
- ////***********SCCB-----OX7670************************//////////
- void delay1ms(uint z)
- {
- uint j,k;
- for(k=z;k;k--)
- {
- for(j=2666;j;j--) ; //此處j不得小于27否則讀不出數據
- }
-
- }
-
- void int_twi_sccb()
- {
- TWBR=50;/*設置SCL的時鐘頻率在19。230根據公式SCL FREQUENCY=CPU Clock frequency/16+2(TWBR)*4的TWPS次方
- */
- }
- /**************************************************/
- //本函數為設置7670寄存器的最底層操作函數,
- //無返回值
- //ADD是要寫的寄存器地址,DATE是向里面寫入的數據
- //
- /*************************************************/
- void write_ov7670_sccb_twi(uchar add,uchar date)//向add指定的地址內寫入指定的數據
- {
- //主發送模式程序/////////////////////////
- TWCR=0xa4;//插入開始新號使能總線,使能START
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測起始信號是否發送?
- while((TWSR&0xf8)!=0x08)
- {
- send_byte(0xf4);
- send_byte(0x21);
- send_byte(0xf4);//出錯
-
- }
-
- send_byte(0xf4);
- send_byte(0x11);
- send_byte(0xf4);//START信號的正確響應碼
-
-
-
-
-
- TWDR=0x42;//寫操作SCCB的器件地址0X42
- TWCR=0x84;//重啟啟動數據的發送
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測數據信號是否發送?
- while((TWSR&0XF8)!=0x18)
- {
-
- send_byte(0xf4);
- send_byte(0x22);
- send_byte(0xf4);
- }
-
- send_byte(0xf4);
- send_byte(0x12);
- send_byte(0xf4);//發送完畢有ACK應答響應碼
-
-
-
-
-
- TWDR=add;//寫操作SCCB的寄存器子地址
- TWCR=0x84;//重啟啟動數據的發送
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測數據信號是否發送?
- while((TWSR&0XF8)!=0x28)
- {
- send_byte(0xf4);
- send_byte(0x23);//出錯
- send_byte(0xf4);
- }
-
- send_byte(0xf4);
- send_byte(0x13);
- send_byte(0xf4);//發送完畢有ACK應答響應碼
-
-
-
- TWDR=date;//寫操作SCCB的寄存器數據
- TWCR=0x84;//重啟啟動數據的發送
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測數據信號是否發送?
- while((TWSR&0XF8)!=0x28)
- {
- send_byte(0xf4);
- send_byte(0x24);//出錯
- send_byte(0xf4);
- }
-
- send_byte(0xf4);
- send_byte(0x14);
- send_byte(0xf4);//發送完畢有ACK應答響應碼
- TWCR=0x94;//STOP信號
-
-
- }
- /**************************************************/
- //本函數為設置7670寄存器的最底層操作函數,
- //返回值為8位的數據
- //ADD是要讀的寄存器地址,
- //
- /*************************************************/
- uchar read_ov7670_sccb_twi(uchar add)//讀取一個add中的一個字節個數據
- {
- uchar date;
- //主發送模式程序/////////////////////////
-
-
- TWCR=0xa4;//插入開始新號使能總線,使能START
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測起始信號是否發送?
- while((TWSR&0xf8)!=0x08)
- {
- send_byte(0xf4);
- send_byte(0x01);
- send_byte(0xf4);//出錯
-
- }
-
- send_byte(0xf4);
- send_byte(0x10);
- send_byte(0xf4);//START信號的正確響應碼
-
-
-
-
-
- TWDR=0x42;//寫操作SCCB的器件寫地址0X42
- TWCR=0x84;//重啟啟動數據的發送
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測數據信號是否發送?
- while((TWSR&0XF8)!=0x18)
- {
-
- send_byte(0xf4);
- send_byte(0x02);
- send_byte(0xf4);
- }
-
- send_byte(0xf4);
- send_byte(0x20);
- send_byte(0xf4);//發送完畢有ACK應答響應碼
-
-
-
-
-
- TWDR=add;//寫操作SCCB的寄存器子地址
- TWCR=0x84;//重啟啟動數據的發送
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測數據信號是否發送?
- while((TWSR&0XF8)!=0x28)
- {
- send_byte(0xf4);
- send_byte(0x03);//出錯
- send_byte(0xf4);
- }
-
- send_byte(0xf4);
- send_byte(0x30);
- send_byte(0xf4);//發送完畢有ACK應答響應碼
-
-
- TWCR=0x94;//STOP信號
-
- delay1ms(10);////無論讀完還是模式轉換后都要等待
-
- //主接收模式程序///////////////////////////////////////////
- TWCR=0xa4;//插入開始新號使能總線,使能START
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測起始信號是否發送?
- while((TWSR&0XF8)!=0x08)
- {send_byte(0xf4);
- send_byte(0x04);//出錯
- send_byte(0xf4);
- }
-
- send_byte(0xf4);
- send_byte(0x40);
- send_byte(0xf4);//START信號的正確響應碼
-
- TWDR=0x43;//寫操作SCCB的器件讀地址0X43
- TWCR=0x84;//重啟啟動數據的發送
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測數據信號是否發送?
- while((TWSR&0XF8)!=0x40)
- {send_byte(0xf4);
- send_byte(0x05);//出錯
- send_byte(0xf4);
- }
-
- send_byte(0xf4);
- send_byte(0x50);
- send_byte(0xf4);//發送完畢有ACK應答響應碼
-
-
- TWCR=0x84;//啟動數據的接收
- delay1ms(1);
- while(0==get_bit(TWCR,7));//檢測數據信號是否發送?
- date=TWDR;
- while((TWSR&0XF8)!=0x58)
- {send_byte(0xf4);
- send_byte(0x06);
- send_byte(0xf4);}//出錯
-
- send_byte(0xf4);
- send_byte(0x60);
- send_byte(0xf4);//發送完畢有NACK應答響應碼
-
-
- TWCR=0x94;//STOP信號
- return(date);
-
- }
- void main()
- {
- uchar inceptdate;//讀出的寄存器數據
- DDRC=0xff;
- PORTC=0xff;
- USART_INT();
- int_twi_sccb();
- inceptdate=read_ov7670_sccb_twi(0x15);//讀寄存器地址為15的數據
- send_byte(0xf4);
- send_byte(inceptdate);//數據顯示
- send_byte(0xf4);
- delay1ms(10);//無論讀完還是寫完都要等等
- write_ov7670_sccb_twi(0x15,0x20);//寫寄存器15的數據位20
- delay1ms(10);
- inceptdate=read_ov7670_sccb_twi(0x15);//再次讀15的數據
- send_byte(0xf4);
- send_byte(inceptdate);//送顯示,已是校驗寫入錢與寫入后的對比
- send_byte(0xf4);
- while(1);
- }
復制代碼
|