/****************************************************************************
|
* Copyright: (C)2014 Î人ÁèÔÆÇ¶ÈëʽʵÑéÊÒ www.emblinux.com
|
* Author: GuoWenxue<guowenxue@gmail.com> 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 Á¬½Ó±í:
|
*| ²Î¿¼<CF7670C-V3 ¼òҪ˵Ã÷.pdf>ºÍ<·Ü¶·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;
|
}
|
|