上文:STM32:硬件IIC,实现EEPROM页写入和连续内存数据读取,但是出现数据出错(上)
https://blog.csdn.net/qq_45689790/article/details/113729858#comments_15148487
按照手册内容实现连续数据的写入(但是不能跨页)和单个数据的写入后。下面介绍硬件IIC跨页写入任意长度的数据。
基本思想:若一页有8个数据
- 确定要写入的地址WriteAddr ,OnePage = 8 - WriteAddr%8 得到的就是第一页需要写入的数据个数
- NumByteToWrite是一共要写入的数据个数,End_page =(NumByteToWrite-OnePage)% 8 得到的是最后一页需要写入的数据个数。
- 确定OnePage 、End_page 后,(NumByteToWrite - OnePage - End_page )/ 8得到的就是中间需要连续写入的数据页数。
举个例子
- WriteAddr = 17,OnePage = 8 - WriteAddr%8 = 7
- NumByteToWrite = 2,那么 End_page =(NumByteToWrite-OnePage)% 8 = 7
- 确定OnePage 、End_page后(NumByteToWrite - OnePage - End_page )% 8 = 1中间需要连续写入1页数据
图示
连续写入数据,大致分为三步,下面是参考代码
void I2C_EE_WaitEepromStandbyState(void); //是等待响应的函数,不再展开
#define I2C_PageSize 8
void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr,
u16 NumByteToWrite)
{
u8 NumOfPage=0,NumOfSingle=0,Addr =0,count=0,temp =0;
Addr = WriteAddr % I2C_PageSize;
count = I2C_PageSize - Addr;
NumOfPage = NumByteToWrite / I2C_PageSize;
NumOfSingle = NumByteToWrite % I2C_PageSize;
// Addr=0,则 WriteAddr 刚好按页对齐 aligned
// 这样就很简单了,直接写就可以,写完整页后
// 把剩下的不满一页的写完即可
if (Addr == 0) {
if (NumOfPage == 0) {
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
else {
while (NumOfPage--) {
I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize;
pBuffer += I2C_PageSize;
}
if (NumOfSingle!=0) {
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
// 如果 WriteAddr 不是按 I2C_PageSize 对齐
// 那就算出对齐到页地址还需要多少个数据,然后
// 先把这几个数据写完,剩下开始的地址就已经对齐
// 到页地址了,代码重复上面的即可
else {
if (NumOfPage== 0) {
if (NumOfSingle > count) {
// temp 的数据要写到写一页
temp = NumOfSingle - count;
I2C_EE_PageWrite(pBuffer, WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count;
pBuffer += count;
I2C_EE_PageWrite(pBuffer, WriteAddr, temp);
I2C_EE_WaitEepromStandbyState();
}
else {
I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
I2C_EE_WaitEepromStandbyState();
}
}
else {
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / I2C_PageSize;
NumOfSingle = NumByteToWrite % I2C_PageSize;
if (count != 0) {
I2C_EE_PageWrite(pBuffer, WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count;
pBuffer += count;
}
while (NumOfPage--) {
I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize;
pBuffer += I2C_PageSize;
}
if (NumOfSingle != 0) {
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
}
参考书籍:《野火STM32库函数开发指南》