#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程序我用过好几次,没发现问题.你可以参考下. |