STM32-I2C驱动-AT24C01-EEPROM

#define AT24C01         //24C01,I2C的时序和普通的有点不同

#define EEPROM_ADDR0xA0
#define I2C_PAGESIZE4       //24C01/01A页缓冲是4个


void I2C_Configuration(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);

/* PB6,7 SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x30;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;

I2C_Cmd(I2C1, ENABLE);
I2C_Init(I2C1, &I2C_InitStructure);
I2C_AcknowledgeConfig(I2C1, ENABLE);       /*允许1字节1应答模式*/

}

 

/* 功能:读取24C02多个字节--256字节,8位地址,A0-A2固定为0,从器件地址为EEPROM_ADDR */
void I2C_ReadS_24C(u8 addr ,u8* pBuffer,u16 no)
{
if(no==0)
return;

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_AcknowledgeConfig(I2C1, ENABLE);     /*允许1字节1应答模式*/

I2C_GenerateSTART(I2C1, ENABLE);     /* 发送起始位 */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/

/*发送器件地址(读)24C01*/
I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


while (no)
{
if(no==1)
{
I2C_AcknowledgeConfig(I2C1, DISABLE);//最后一位后要关闭应答的
I2C_GenerateSTOP(I2C1, ENABLE);//发送停止位
}

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
*pBuffer = I2C_ReceiveData(I2C1);
pBuffer++;
/* Decrement the read bytes counter */
no--;
}
//再次允许应答模式
I2C_AcknowledgeConfig(I2C1, ENABLE);
}

 

/* 判断是否准备好再写入,忙就停发地址 直到器件有应答 */
void I2C_Standby_24C(void)
{
vu16 SR1_Tmp;
do
{
I2C_GenerateSTART(I2C1, ENABLE);  /*起始位*/
SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);  /*读SR1*/
/*器件地址(写)*/

I2C_Send7bitAddress(I2C1, 0, I2C_Direction_Transmitter);

}while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));

I2C_ClearFlag(I2C1, I2C_FLAG_AF);        /*清除应答错误标志*/
I2C_GenerateSTOP(I2C1, ENABLE);        /*停止位*/
}

 

/* i2c 写一个字节*/
void I2C_ByteWrite_24C(u8 addr,u8 dat)
{
//start
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));


//device address
I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

//data 写一个字节
I2C_SendData(I2C1, dat);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

//stop
I2C_GenerateSTOP(I2C1, ENABLE);

I2C_Standby_24C();
}

 

/* 写入一页(以内) */
void I2C_PageWrite_24C(u8 addr,u8* pBuffer, u8 no)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

/*起始位*/
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));


I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

while(no--)
{
I2C_SendData(I2C1, *pBuffer);
pBuffer++;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}

/*停止位*/
I2C_GenerateSTOP(I2C1, ENABLE);
}

 

/* 页写入,最多允许一次写入8个字节 */
void I2C_WriteS_24C(u8 addr,u8* pBuffer, u16 no)
{
u8 temp;

//1.先把页不对齐的部分写入
temp=addr % I2C_PAGESIZE;
if(temp)
{
temp=I2C_PAGESIZE-temp;
I2C_PageWrite_24C(addr,pBuffer, temp);
no-=temp;
addr+=temp;
pBuffer+=temp;
I2C_Standby_24C();
}
//2.从页对齐开始写
while(no)
{
if(no>=I2C_PAGESIZE)
{
I2C_PageWrite_24C(addr,pBuffer, I2C_PAGESIZE);
no-=I2C_PAGESIZE;
addr+=I2C_PAGESIZE;
pBuffer+=I2C_PAGESIZE;
I2C_Standby_24C();
}
else
{
I2C_PageWrite_24C(addr,pBuffer, no);
no=0;
I2C_Standby_24C();
}
}
}


//测试用
void I2C_Test(void)
{
u8 i;
u8 I2c_Buf[128];

I2C_Standby_24C();

//填充缓冲
for(i=0;i<128;i++)
I2c_Buf[i]=i;

//写
I2C_WriteS_24C(1,I2c_Buf,120);

//清缓冲
for(i=0;i<128;i++)
I2c_Buf[i]=0;

//读
I2C_ReadS_24C(1,I2c_Buf,80);

for(i=1;i<120;i++)
{
if(I2c_Buf[i]!=i)
{
while(1);
}
}

}

 

 

就看这里 确定是否正常~!

其实 都是 while 这种 硬等待 导致屡次调不通 务必加入 超时判断。

简单的像

i=0;

while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))&&i<12000);i++

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值