STM32: Hardware IIC, realize EEPROM write data across pages, (continued from above)

Above: STM32: Hardware IIC, to achieve EEPROM page writing and continuous memory data reading, but data errors occur (top)

https://blog.csdn.net/qq_45689790/article/details/113729858#comments_15148487

After writing continuous data (but not across pages) and writing single data according to the contents of the manual. The following introduces the hardware IIC to write data of arbitrary length across pages.

Basic idea : If there are 8 data on a page

  1. Determine the address WriteAddr to be written , OnePage = 8-WriteAddr%8 What you get is the number of data to be written on the first page
  2. NumByteToWrite is the total number of data to be written, End_page = (NumByteToWrite-OnePage)% 8 is the number of data to be written on the last page.
  3. After determining OnePage and End_page, (NumByteToWrite-OnePage-End_page) / 8 is the number of data pages that need to be written continuously in the middle.

for example

  1. WriteAddr = 17,OnePage = 8 - WriteAddr%8 = 7
  2. NumByteToWrite = 2,那么 End_page =(NumByteToWrite-OnePage)% 8 = 7
  3. After confirming OnePage and End_page (NumByteToWrite-OnePage-End_page)% 8 = 1 1 page of data needs to be written continuously in the middle

Icon

Insert picture description here

Continuously write data, roughly divided into three steps, the following is the reference code


void I2C_EE_WaitEepromStandbyState(void); //是等待响应的函数,不再展开  

 /**
 * @brief 将缓冲区中的数据写到 I2C EEPROM 中
 * @param
 * @arg pBuffer:缓冲区指针
 * @arg WriteAddr:写地址
 * @arg NumByteToWrite:写的字节数
 * @retval 无
 */
  #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;
 
	/*mod 运算求余,若 writeAddr 是 I2C_PageSize 整数倍,
	运算结果 Addr 值为 0*/
	Addr = WriteAddr % I2C_PageSize;
 
	/*差 count 个数据值,刚好可以对齐到页地址*/
	count = I2C_PageSize - Addr;
	
	/*计算出要写多少整数页*/
	NumOfPage = NumByteToWrite / I2C_PageSize;
 
	/*mod 运算求余,计算出剩余不满一页的字节数*/
	NumOfSingle = NumByteToWrite % I2C_PageSize;
	
	// Addr=0,则 WriteAddr 刚好按页对齐 aligned
	// 这样就很简单了,直接写就可以,写完整页后
	// 把剩下的不满一页的写完即可
	if (Addr == 0) {
    
    
		/* 如果 NumByteToWrite < I2C_PageSize */
		if (NumOfPage == 0) {
    
    
			I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
			I2C_EE_WaitEepromStandbyState();
		}
		/* 如果 NumByteToWrite > I2C_PageSize */
		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 {
    
    
		/* 如果 NumByteToWrite < I2C_PageSize */
		if (NumOfPage== 0) {
    
    
			/*若 NumOfSingle>count,当前面写不完,要写到下一页*/
				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 {
    
     /*若 count 比 NumOfSingle 大*/
						I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
						I2C_EE_WaitEepromStandbyState();
					}
		}
		/* 如果 NumByteToWrite > I2C_PageSize */
		else {
    
    
			/*地址不对齐多出的 count 分开处理,不加入这个运算*/
			NumByteToWrite -= count;
			NumOfPage = NumByteToWrite / I2C_PageSize;
			NumOfSingle = NumByteToWrite % I2C_PageSize;
			
			/*先把 WriteAddr 所在页的剩余字节写了*/
			if (count != 0) {
    
    
				I2C_EE_PageWrite(pBuffer, WriteAddr, count);
				I2C_EE_WaitEepromStandbyState();
				/*WriteAddr 加上 count 后,地址就对齐到页了*/
				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库函数开发指南》

Guess you like

Origin blog.csdn.net/qq_45689790/article/details/114070956