新手上路
- 积分
- 37
- 金钱
- 37
- 注册时间
- 2026-2-9
- 在线时间
- 16 小时
|
1金钱
AT24C512 在硬件读取时即读取正常,但在块读取时加电后只能正确读取一次,以后只读取第一个字节,其他的都是0XFF
代码如下。
void I2C_Config()
{ RCC->APB2ENR|=1<<3; //使能PORTB时钟
RCC->APB1ENR|=1<<21; //使能I2C1时钟
GPIOB->CRL&=0X00FFFFFF;
GPIOB->CRL|=0XFF000000;//PB.5 推挽输出
GPIOB->ODR|=1<<6; //PB.5 输出高
I2C1->TRISE=0X25;
I2C1->CR2=0X0024;
I2C1->CCR=0XB4;
I2C1->CR1=0X0401;
}
//***********************************************************************************************************************************************************************************
u8 AT24Cxxx_ReadOneByte(u16 ReadAddr)
{ u8 temp=0;
I2C1->CR1|=0X0100; //起始信号
while(!(I2C1->SR1&(1<<0))); //等待起始信号发送完成
if(EE_TYPE>AT24C16)
{ I2C1->DR=(0XA0); //发送写命令
while(!(I2C1->SR1&(1<<1)));
I2C1->DR=(ReadAddr>>8);//发送高地址
}else
I2C1->DR=0XA0+(ReadAddr/256<<1);
while(!(I2C1->SR1&(1<<1))); //等待地址发送完成
temp=I2C1->SR2;
I2C1->DR=ReadAddr%256;
while(!(I2C1->SR1&(1<<7))); //等待发送缓冲区空
I2C1->CR1|=0X0100;
while(!(I2C1->SR1&(1<<0))); //等待起始信号发送完成
I2C1->DR=0XA1;
while(!(I2C1->SR1&(1<<1))); //等待地址发送完成
temp=I2C1->SR2;
while(!(I2C1->SR1&(1<<6))); //等待收到数据
temp=I2C1->DR;
I2C1->CR1&=~0X0400; //关闭应答
I2C1->CR1|=0X0200; //产生停止信号
return temp;
}
void AT24Cxxx_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{ u8 temp;
I2C1->CR1|=0X0100; //起始信号
while(!(I2C1->SR1&(1<<0))); //等待起始信号发送完成
if(EE_TYPE>AT24C16)
{ I2C1->DR=(0XA0); //发送写命令
while(!(I2C1->SR1&(1<<1)));
I2C1->DR=(WriteAddr>>8);//发送高地址
}else
I2C1->DR=0XA0+((WriteAddr/256)<<1);
while(!(I2C1->SR1&(1<<1)));
temp=I2C1->SR2;
I2C1->DR=WriteAddr%256; //发送低地址
while(!(I2C1->SR1&(1<<7)));
I2C1->DR=DataToWrite; //发送字节
while(!(I2C1->SR1&(1<<7)));
I2C1->CR1|=0X0200; //产生停止信号
delay_ms(10); //EEPROM的写入速度比较慢,加入延迟
}
//***********************************************************************************************************************************************************************************
#if AT24Cx_Write
void AT24Cxxx_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{ while(NumToWrite--)
{ AT24Cxxx_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}
}
#else
void AT24Cxxx_PWrite(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{ u8 temp;
I2C1->CR1|=0X0100; //起始信号
while(!(I2C1->SR1&(1<<0))); //等待起始信号发送完成
if(EE_TYPE>AT24C16)
{ I2C1->DR=(0XA0); //发送写命令
while(!(I2C1->SR1&(1<<1)));
I2C1->DR=(WriteAddr>>8);//发送高地址
}else
I2C1->DR=0XA0+((WriteAddr/256)<<1);
while(!(I2C1->SR1&(1<<1)));
temp=I2C1->SR2;
I2C1->DR=WriteAddr%256; //发送低地址
while(!(I2C1->SR1&(1<<7)));
while(NumToWrite--)
{ I2C1->DR=*pBuffer++;
while(!(I2C1->SR1&(1<<7)));
}
I2C1->CR1|=0X0200; //产生停止信号
delay_ms(10); //EEPROM的写入速度比较慢,加入延迟
}
////***********************************************************************************************************************************************************************************
void AT24Cxxx_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{ u8 i;
w: if (WriteAddr%AT24+NumToWrite<=AT24)
{ AT24Cxxx_PWrite(WriteAddr,pBuffer,NumToWrite);goto p; }
if (WriteAddr%AT24+NumToWrite>AT24)
{ i=AT24-WriteAddr%AT24;
AT24Cxxx_PWrite(WriteAddr,pBuffer,i);
if (WriteAddr==0)
{ NumToWrite=NumToWrite-AT24;
WriteAddr+=AT24;
pBuffer+=AT24;
}else
{ NumToWrite=NumToWrite-i;
WriteAddr+=i;
pBuffer+=i;
}
goto w;
}
p:i++;
}
#endif
//--------------------------------------------------------------------------------
#if AT24Cx_Read
void AT24Cxxx_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{ while(NumToRead)
{ *pBuffer++=AT24Cxxx_ReadOneByte(ReadAddr++);
NumToRead--;
}
}
#else
void AT24Cxxx_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{ u8 temp=0;
I2C1->CR1|=0X0100; //起始信号
while(!(I2C1->SR1&(1<<0))); //等待起始信号发送完成
if(EE_TYPE>AT24C16)
{ I2C1->DR=(0XA0); //发送写命令
while(!(I2C1->SR1&(1<<1)));
I2C1->DR=(ReadAddr>>8);//发送高地址
}else
I2C1->DR=0XA0+(ReadAddr/256<<1);
while(!(I2C1->SR1&(1<<1))); //等待地址发送完成
temp=I2C1->SR2;
I2C1->DR=ReadAddr%256;
while(!(I2C1->SR1&(1<<7))); //等待发送缓冲区空
I2C1->CR1|=0X0100; //起始信号
while(!(I2C1->SR1&(1<<0))); //等待起始信号发送完成
I2C1->DR=0XA1;
while(!(I2C1->SR1&(1<<1))); //等待地址发送完成
temp=I2C1->SR2;
while(NumToRead--)
{ while(!(I2C1->SR1&(1<<6))); //等待收到数据
temp=I2C1->SR2;
*pBuffer++=I2C1->DR;
}
I2C1->CR1&=~0X0400; //关闭应答
I2C1->CR1|=0X0200; //产生停止信号
}
#endif
|
|