正文
EEPROM读写需要注意
EEPROM读写操作之间,距离下一次操作需要留一定时间,给EEPROM芯片处理数据的时间,不能立即去读写的数据。
EEPROM多字节读写,需要注意页对齐的问题,不然会出现数据没有成功写入。
情况一:单字节连续读写
具体I2C配置和应用层程序请参考前文
主函数,main.c
uint8_t wr_data = 0xfe;
uint8_t rd_data = 0;
BSP_UART_Init();
BSP_I2C_Init();
BSP_I2C_WR_Byte(wr_data,EEPROM_ADDRESS7,0x00);
BSP_I2C_ReadBuffer(&rd_data,EEPROM_ADDRESS7,0x00,1);
printf("%x",rd_data);
会发现此时会报错I2C读,EV6和EV8事件,查询STM32F1参考手册,会发现从设备对ADDR无应答。
改进:此时加入等待从设备程序
主函数,main.c
uint8_t wr_data = 0xfe;
uint8_t rd_data = 0;
BSP_UART_Init();
BSP_NVIC_Config();
BSP_I2C_Init();
BSP_I2C_WR_Byte(wr_data,EEPROM_ADDRESS7,0x00);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
BSP_I2C_ReadBuffer(&rd_data,EEPROM_ADDRESS7,0x00,1);
printf("%x",rd_data);
即可正常读出程序。
情况二:多字节地址对齐
具体I2C配置和应用层程序请参考前文
主函数,main.c
uint8_t wr_data[5] = {0xfe,0xfd,0xfc,0xfb,0xfa};
uint8_t rd_data[5] = {0};
BSP_UART_Init();
BSP_NVIC_Config();
BSP_I2C_Init();
BSP_I2C_WriteBuffer(wr_data,EEPROM_ADDRESS7,0x04,sizeof(wr_data)/sizeof(uint8_t));
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
BSP_I2C_ReadBuffer(rd_data,EEPROM_ADDRESS7,0x04,sizeof(rd_data)/sizeof(uint8_t));
for(int i = 0;i<5;i++)
{
printf("rd_data[%d] = %x\r\n",i,rd_data);
}
此时EEPROM理想存储情况
这是由于EEPROM多字节写入必须要考虑页对齐的情况,同时一次写入不能超过EEPROM页大小。
1Kbit/2Kbit大小的EEPROM最多写入8Byte;
4Kbit/8Kbit/16Kbit大小的EEPROM最多写入16Byte;
void BSP_I2C_EE_Page_BufferWrite(uint8_t *pBuffer,uint8_t WriteAddr,uint8_t NumBytetoWrite)
{
if(NumBytetoWrite > EE_PAGE_SIZE)
NumBytetoWrite = EE_PAGE_SIZE;
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,NumBytetoWrite);
}
不定长字节写入,没有页写入的最大字节8Byte限制
void BSP_I2C_EE_BufferWrite(uint8_t *pBuffer,uint8_t WriteAddr,uint8_t NumBytetoWrite)
{
uint8_t NumofPage = 0,NumofSingle = 0,Addr = 0,Addr_Cnt = 0,Addr_Temp = 0;
Addr = WriteAddr % EE_PAGE_SIZE;
Addr_Cnt = EE_PAGE_SIZE - Addr;
NumofPage = NumBytetoWrite / EE_PAGE_SIZE;
NumofSingle = NumBytetoWrite % EE_PAGE_SIZE;
if(Addr == 0){
if(NumofPage == 0){
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,NumBytetoWrite);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
}
else{
while(NumofPage--){
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,EE_PAGE_SIZE);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
WriteAddr += EE_PAGE_SIZE;
pBuffer += EE_PAGE_SIZE;
}
if(NumofSingle != 0){
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,NumofSingle);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
}
}
}
else{
if(NumofPage == 0){
if(NumofSingle > Addr_Cnt){
Addr_Temp = NumofSingle - Addr_Cnt;
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,Addr_Cnt);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
WriteAddr += Addr_Cnt;
pBuffer += Addr_Cnt;
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,Addr_Temp);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
}
else{
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,NumBytetoWrite);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
}
}
else{
NumBytetoWrite -= Addr_Cnt;
NumofPage = NumBytetoWrite / EE_PAGE_SIZE;
NumofSingle = NumBytetoWrite % EE_PAGE_SIZE;
if(Addr_Cnt != 0){
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,Addr_Cnt);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
WriteAddr += Addr_Cnt;;
pBuffer += Addr_Cnt;
}
while(NumofPage--){
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,EE_PAGE_SIZE);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
WriteAddr += EE_PAGE_SIZE;
pBuffer += EE_PAGE_SIZE;
}
if(NumofSingle != 0){
BSP_I2C_KeepWrite(pBuffer,EEPROM_ADDRESS7,WriteAddr,NumofSingle);
BSP_I2C_WaitStandByState(EEPROM_ADDRESS7);
}
}
}
}
上述代码主要分为以下几种情况。
写入的数据的首地址页对齐。
数据长度没有超过一页的大小(8Byte),则直接写入。
数据长度超过一页的大小(8Byte),先按页写入,再将多余的写入新的一页。
写入的数据的首地址并不是页对齐。
数据长度没有超过一页的大小(8Byte)
数据首地址距离页尾的空间不足以放下整个数据,则先补全该页,再将剩余的数据写到下一页。
数据首地址距离页尾的空间足以放下整个数据,则直接写入。
数据长度超过一页的大小(8Byte)
先补全该页,再按页写入,再将剩余的数据写到下一页。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/ZipingPan/article/details/137314177
|
|