/**************************************************************************** * Copyright: (C)2014 Î人ÁèÔÆÇ¶ÈëʽʵÑéÊÒ www.emblinux.com * Author: GuoWenxue QQ: 281143292 * Description: ·Ü¶·STM32v5¿ª·¢°åGPIOÄ£ÄâÉãÏñÍ·SCCB(Serial Camera Control Bus)µÄʵÏÖ, * SCCBµÄ¹¤×÷·½Ê½ÓëI2CÊ®·ÖÀàËÆ£¬ËûʹÓÃOV¹«Ë¾¶¨ÒåµÄ3Ïß´®ÐÐÉãÏñÍ·¿ØÖÆ×ÜÏߣ¬ * ¿ÉÒÔ¿ØÖƴ󲿷ÖOVϵÁÐͼÐδ«¸ÐÆ÷¡£SCCBÒ²¿ÉÒÔ¹¤×÷ÔÚ2Ïß´®ÐÐģʽ(SIOCÓëSIOD). * STM32ÉÏʹÓÃPE2ºÍPE3·Ö±ðÁ¬½ÓOV7670µÄSCCBʱÖÓ¿ÚºÍÊý¾Ý¿Ú,¸Ã´úÂëÖ÷ҪʹÓà * PE2ºÍPE3µÄGPIO¿ÚÄ£ÄâSCCB(Ò²¼´I2C)×ÜÏßЭÒé * * ChangeLog: * °æ±¾ºÅ ÈÕÆÚ ×÷Õß ËµÃ÷ * V1.0.0 2014.08.25 GuoWenxue ·¢²¼¸Ã°æ±¾ ****************************************************************************/ /* CF7670C-V3ÉãÏñÍ·Ä£¿éPin¹Ü½ÅºÍSTM32v5 Á¬½Ó±í: *| ²Î¿¼ºÍ<·Ü¶·STM32¿ª·¢°åV5Ô­Àíͼ.pdf> *+---------------------------------------+------------------------------+ *| CF7670C-V3ÉãÏñÍ·Ä£¿éÒý½Å¼°ËµÃ÷ | STM32¶ËÒý½ÅÁ¬½Ó¼°ËµÃ÷ | *+---------------------------------------+------------------------------+ *| Pin1-VCC(3.3V,·½º¸Å̱ê¼ÇµÄΪµÚÒ»½Å) | 3.3V | *| Pin2-GND | GND | *| Pin3-SCL(SCCB_SCL²»´øÉÏÀ­µç×è) | PE2 | *| Pin4-SDA(SCCB_SDA ´ø4.7KÉÏÀ­µç×è) | PE3 | *| Pin5-VSYNC(OV7670 ֡ͬ²½ÐźÅ) | PE4 | *| Pin6-HREF(OV7670 ÐÐͬ²½ÐźÅ) | NC | *| Pin7-WEN(FIFO(AL422)дÔÊÐí,¸ßµçƽÓÐЧ | PE5 | *| Pin8-XCLK(NC/RE# ¿Õ½Å) | NC | *| Pin9-RRST(FIFO¶ÁµØÖ·¸´Î» | PE6 | *| Pin10-OE#(FIFOÊý¾ÝÊä³öʹÄÜ,µÍµçƽÓÐЧ | GND | *| Pin11-RCK#(FIFO¶ÁÊý¾ÝʱÖÓ | PD12 | *| Pin12-GND | GND | *| | | *| Pin13-D0 FIFOÊý¾Ý¿ÚÊä³öBIT0 | PC0 | *| Pin14-D1 FIFOÊý¾Ý¿ÚÊä³öBIT1 | PC1 | *| Pin15-D2 FIFOÊý¾Ý¿ÚÊä³öBIT2 | PC2 | *| Pin16-D3 FIFOÊý¾Ý¿ÚÊä³öBIT3 | PC3 | *| Pin17-D4 FIFOÊý¾Ý¿ÚÊä³öBIT4 | PC4 | *| Pin18-D5 FIFOÊý¾Ý¿ÚÊä³öBIT5 | PC5 | *| Pin19-D6 FIFOÊý¾Ý¿ÚÊä³öBIT6 | PC6 | *| Pin20-D7 FIFOÊý¾Ý¿ÚÊä³öBIT7 | PC7 | *+------------------+-----------------+---------------------------------+ */ #include "stm32v5_sccb.h" /* ÅäÖÃÁ¬½ÓOV7670µÄSCCB_SCL(PE2)ºÍSCCB_SDA(PE3)ΪGPIOģʽģÄâ*/ void init_sccb_gpio(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); /* Configure I2C pins: PE2->SCL and PE3->SDA */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP ;// GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; GPIO_Init(GPIOE, &GPIO_InitStructure); } /* I2C ×ÜÏßʱÖÓÑÓʱº¯Êý */ static void I2C_delay(void) { unsigned short i = 200; /* ÕâÀï¿ÉÒÔÓÅ»¯ËÙ¶È */ while(i) { i--; } } /* I2C×ÜÏß¿ªÊ¼ÐźŠ*/ static int I2C_Start(void) { SDA_H; I2C_delay(); SCL_H; I2C_delay(); SDA_L; I2C_delay(); SCL_L; I2C_delay(); return ENABLE; } /* I2C×ÜÏßÍ£Ö¹ÐźŠ*/ static void I2C_Stop(void) { SDA_L; I2C_delay(); SCL_H; I2C_delay(); SDA_H; I2C_delay(); } /* I2C×ÜÏßSDAÊäÈë */ void I2C_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); } /* I2C×ÜÏßSDAÊä³ö */ void I2C_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP ;// GPIO_Init(GPIOE, &GPIO_InitStructure); } /* I2C×ÜÏßACKÐźŠ*/ static void I2C_Ack(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } /* I2C×ÜÏßNAKÐźŠ*/ static void I2C_NoAck(void) { SDA_H; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); SDA_L; I2C_delay(); } /* I2C×ÜÏߵȴýACKÐźŠ*/ static int I2C_WaitAck(void) { I2C_IN(); I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { SCL_L; return DISABLE; } SCL_L; I2C_delay(); I2C_OUT(); I2C_delay(); return ENABLE; } /* I2C×ÜÏß·¢ËÍÒ»¸ö×Ö½ÚÊý¾Ý, Êý¾Ý´Ó¸ßλµ½µÍλ */ static void I2C_SendByte(uint8_t SendByte) { uint8_t i=8; while(i--) { //SCL_L; //I2C_delay(); if(SendByte&0x80) SDA_H; else SDA_L; SendByte<<=1; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } } /* I2C×ÜÏß½ÓÊÕÒ»¸ö×Ö½ÚÊý¾Ý, Êý¾Ý´Ó¸ßλµ½µÍλ */ static int I2C_ReceiveByte(void) { uint8_t i=8; uint8_t ReceiveByte=0; SDA_H; while(i--) { ReceiveByte<<=1; SCL_L; I2C_delay(); SCL_H; I2C_IN(); I2C_delay(); if(SDA_read) { ReceiveByte|=0x01; } } SCL_L; I2C_OUT(); return ReceiveByte; } /******************************************************************************* * Function Name : I2C_WriteByte * Description : дһ×Ö½ÚÊý¾Ý * Input : - WriteAddress: ´ýдÈëµØÖ· * - SendByte: ´ýдÈëÊý¾Ý * - DeviceAddress: Æ÷¼þÀàÐÍ * Output : None * Return : ·µ»ØÎª:=1³É¹¦Ð´Èë,=0ʧ°Ü * Attention : None *******************************************************************************/ int I2C_WriteByte( uint16_t WriteAddress , uint8_t SendByte , uint8_t DeviceAddress) { if(!I2C_Start()) { return DISABLE; } I2C_delay(); I2C_SendByte( DeviceAddress ); /* Æ÷¼þµØÖ· */ if( !I2C_WaitAck() ) { I2C_Stop(); return DISABLE; } I2C_delay(); I2C_SendByte((uint8_t)(WriteAddress & 0x00FF)); /* ÉèÖÃµÍÆðʼµØÖ· */ I2C_WaitAck(); I2C_delay(); I2C_SendByte(SendByte); I2C_WaitAck(); I2C_delay(); I2C_Stop(); I2C_delay(); return ENABLE; } /******************************************************************************* * Function Name : I2C_ReadByte * Description : ¶Áȡһ´®Êý¾Ý * Input : - pBuffer: ´æ·Å¶Á³öÊý¾Ý * - length: ´ý¶Á³ö³¤¶È * - ReadAddress: ´ý¶Á³öµØÖ· * - DeviceAddress: Æ÷¼þÀàÐÍ * Output : None * Return : ·µ»ØÎª:=1³É¹¦¶ÁÈë,=0ʧ°Ü * Attention : None *******************************************************************************/ int I2C_ReadByte(uint8_t* pBuffer, uint16_t length, uint8_t ReadAddress, uint8_t DeviceAddress) { if(!I2C_Start()) { return DISABLE; } I2C_SendByte( DeviceAddress ); /* Æ÷¼þµØÖ· */ if( !I2C_WaitAck() ) { I2C_Stop(); return DISABLE; } I2C_SendByte( ReadAddress ); /* ÉèÖÃµÍÆðʼµØÖ· */ I2C_WaitAck(); I2C_Stop(); if(!I2C_Start()) { return DISABLE; } I2C_SendByte( DeviceAddress + 1 ); /* Æ÷¼þµØÖ· */ if(!I2C_WaitAck()) { I2C_Stop(); return DISABLE; } while(length) { *pBuffer = I2C_ReceiveByte(); if(length == 1) { I2C_NoAck(); } else { I2C_Ack(); } pBuffer++; length--; } I2C_Stop(); return ENABLE; }