#define SCK_High GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define SCK_Low GPIO_ResetBits(GPIOA,GPIO_Pin_1)
#define SDA_High GPIO_SetBits(GPIOA,GPIO_Pin_3)
#define SDA_Low GPIO_ResetBits(GPIOA,GPIO_Pin_3)
#define SCK_read GPIOA->IDR & GPIO_Pin_1
#define SDA_read GPIOA->IDR & GPIO_Pin_3
typedef enum
{
FALSE = 0,
TRUE = !FALSE
} bool;
void I2C_delay()
{
u8 i=100;
while(i)
{
i--;
}
}
bool I2C_Start()
{
SDA_High;
SCK_High;
I2C_delay();
if(!SDA_read)
{
return FALSE; //SDA線為低電平則總線忙,退出
}
SDA_Low;
I2C_delay();
if(SDA_read)
{
return FALSE; //SDA線為高電平則總線出錯,退出
}
SDA_Low;
I2C_delay();
return TRUE;
}
void I2C_Stop()
{
SCK_Low;
I2C_delay();
SDA_Low;
I2C_delay();
SCK_High;
I2C_delay();
SDA_High;
I2C_delay();
}
void I2C_Ack()
{
SCK_Low;
I2C_delay();
SDA_Low;
I2C_delay();
SCK_High;
I2C_delay();
SCK_Low;
I2C_delay();
}
void I2C_NoAck()
{
SCK_Low;
I2C_delay();
SDA_High;
I2C_delay();
SCK_High;
I2C_delay();
SCK_Low;
I2C_delay();
}
bool I2C_WaitAck() //返回TRUE有ACK,FALSE無ACK
{
SCK_Low;
I2C_delay();
SDA_High;
I2C_delay();
SCK_High;
I2C_delay();
if(SDA_read)
{
SCK_Low;
return FALSE;
}
SCK_Low;
return TRUE;
}
void I2C_SendByte(u8 SendByte) //數據從高位到低位//
{
u8 i=8;
while(i--)
{
SCK_Low;
I2C_delay();
if(SendByte&0x80)
{
SDA_High;
}
else
{
SDA_Low;
}
SendByte<<=1;
I2C_delay();
SCK_High;
I2C_delay();
}
SCK_Low;
}
u8 I2C_ReadByte(void) //數據從高位到低位//
{
u8 i=8;
u8 data=0;
SDA_High;
while(i--)
{
data<<=1;
SCK_Low;
I2C_delay();
SCK_High;
I2C_delay();
if(SDA_read)
{
data|=0x01;
}
}
SCK_Low;
return data;
}
//===================24C02 讀寫程序===========================
bool AT24C02_WriteByte(u8 SendByte, u8 Address)
{
if(!I2C_Start())
{
return FALSE;
}
I2C_SendByte(0xa0);
if(!I2C_WaitAck())
{
I2C_Stop();
return FALSE;
}
I2C_SendByte(Address);
I2C_WaitAck();
I2C_SendByte(SendByte);
I2C_WaitAck();
I2C_Stop();
Delay(15); //加個延時等待寫完
return TRUE;
}
bool AT24C02_ReadByte(u8* data,u8 Adress)
{
if(!I2C_Start()) //如果總線忙,則返回失敗.
return FALSE;
I2C_SendByte(0xa0);
if(!I2C_WaitAck()) //如果沒有得到應答,則返回失敗.
{
I2C_Stop();
return FALSE;
}
I2C_SendByte(Adress);
I2C_WaitAck();
I2C_Start();
I2C_SendByte(0xa1);
I2C_WaitAck();
*data = I2C_ReadByte();
I2C_Stop();
return TRUE;
}
這個是我以前學I2C時的程序,和24C02的程序,不過是32的,你稍微改下,用在51也很簡單,24C02的兩個函數也就學習的時候用過下,后面基本沒碰過.但前面的I2C程序我用過好幾次,沒發現問題.你可以參考下. |