#include"AT24C256.h"
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB的时钟
GPIO_InitStructure.GPIO_Pin=SCL|SDA;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//输出
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
// GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL; //上拉
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; //高速GPIO
GPIO_Init(GPIOB,&GPIO_InitStructure);
SCL_H();
SDA_H();
}
void delay2us(u32 nus)
{
u32 i;
while (nus--)
for (i = 11; i > 0; i--)
;
}
void I2C_delay(void)
{
u8 i=100; //这里可以优化速度 ,经测试最低到5还能写入
while(i)
{
i--;
}
}
u8 I2C_Start(void)
{
SDA_OUT();
SDA_H();
SCL_H();
I2C_delay();
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L();
I2C_delay();
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SCL_L();
return TRUE;
}
void I2C_Stop(void)
{
SDA_OUT();
SCL_L();
SDA_L();
I2C_delay();
SCL_H();
I2C_delay();
SDA_H();
I2C_delay();
}
void I2C_Ack(void)
{
SDA_OUT();
SCL_L();
SDA_L();
I2C_delay();
SCL_H();
I2C_delay();
SCL_L();
}
void I2C_NoAck(void)
{
SDA_OUT();
SCL_L();
SDA_H();
I2C_delay();
SCL_H();
I2C_delay();
SCL_L();
}
u8 I2C_WaitAck(void)
{
u8 ucErrTime=0;
SDA_IN();
SCL_H();I2C_delay();
SDA_H();I2C_delay();
while(SDA_read)
{
ucErrTime++;
if(ucErrTime>250)
{
I2C_Stop();
return FALSE;
}
}
SCL_L();
return TRUE;
}
void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
u8 i;
SDA_OUT();
SCL_L();
for(i=0;i<8;i++)
{
if(SendByte&0x80)
SDA_H();
else
SDA_L();
SendByte<<=1;
I2C_delay();
SCL_H();
I2C_delay();
SCL_L();
I2C_delay();
}
}
u8 I2C_ReceiveByte(void) //数据从高位到低位//
{
u8 i;
u8 ReceiveByte=0;
SDA_IN();
for(i=0;i<8;i++)
{
SCL_L();
I2C_delay();
SCL_H();
ReceiveByte<<=1;
I2C_delay();
if(SDA_read)
{
// ReceiveByte|=0x01;
ReceiveByte++;
}
}
return ReceiveByte;
}
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
u8 temp=0;
I2C_Start();
I2C_SendByte(0XA0); //发送写命令
I2C_WaitAck();
I2C_SendByte(ReadAddr>>8);//发送高地址
I2C_WaitAck();
I2C_SendByte(ReadAddr%256); //发送低地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(0XA1); //进入接收模式
I2C_WaitAck();
temp=I2C_ReceiveByte();
I2C_Stop();//产生一个停止条件
return temp;
}
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
I2C_Start();
I2C_SendByte(0XA0); //发送写命令
I2C_WaitAck();
I2C_SendByte(WriteAddr>>8);//发送高地址
I2C_WaitAck();
I2C_SendByte(WriteAddr%256); //发送低地址
I2C_WaitAck();
I2C_SendByte(DataToWrite); //发送字节
I2C_WaitAck();
I2C_Stop();//产生一个停止条件
delay2us(100000);
}
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
while(NumToRead)
{
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
NumToRead--;
}
}
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
while(NumToWrite--)
{
AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}
}
void AT24CXX_BufferWriter(u16 WriteAddr, u8 *pBuffer,u32 NumToWrite)
{
u32 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
delay2us(50);
Addr=WriteAddr % I2C_PageSize;
count = I2C_PageSize-Addr;
if(count>=NumToWrite){
AT24CXX_Write( WriteAddr,pBuffer,NumToWrite);
Delay10us(10);
}
else
{
NumOfPage=(NumToWrite-count)/I2C_PageSize;
NumOfSingle=(NumToWrite-count)%I2C_PageSize;
AT24CXX_Write( WriteAddr,pBuffer,count);
WriteAddr+=count;
pBuffer+=count;
while(NumOfPage--)
{
AT24CXX_Write( WriteAddr,pBuffer,I2C_PageSize);
Delay10us(10);
WriteAddr += I2C_PageSize;
pBuffer += I2C_PageSize;
}
if(NumOfSingle !=0)
{
AT24CXX_Write( WriteAddr,pBuffer,NumOfSingle);
Delay10us(10);
}
}
Delay10us(10);
}
- 1
- 2
前往页