STM32:ハードウェアIIC、ページ間でEEPROM書き込みデータを実現(上から続く)

上:STM32:ハードウェアIIC、EEPROMページの書き込みと継続的なメモリデータの読み取りを実現しますが、データエラーが発生します(上)

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

マニュアルの内容に従って、連続データ(ただしページ間ではない)を書き込み、単一データを書き込んだ後。以下に、ページ間で任意の長さのデータを書き込むためのハードウェアIICを紹介します。

基本的な考え方:1ページに8つのデータがある場合

  1. 書き込むアドレスWriteAddrを決定します。OnePage = 8-WriteAddr%8取得するのは、最初のページに書き込まれるデータの数です。
  2. NumByteToWriteは、書き込まれるデータの総数です。End_page=(NumByteToWrite-OnePage)%8は、最後のページに書き込まれるデータの数です。
  3. OnePageとEnd_pageを決定した後、(NumByteToWrite-OnePage-End_page)/ 8は、途中で継続的に書き込む必要のあるデータページの数です。

例えば

  1. WriteAddr = 17、OnePage = 8-WriteAddr%8 = 7
  2. NumByteToWrite = 2、那么End_page =(NumByteToWrite-OnePage)%8 = 7
  3. OnePageとEnd_page(NumByteToWrite-OnePage-End_page)を確認した後%8 = 11ページのデータを途中で継続的に書き込む必要があります

アイコン

ここに画像の説明を挿入

大まかに3つのステップに分けてデータを連続的に書き込む、以下はリファレンスコードです


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库函数开发指南》

おすすめ

転載: blog.csdn.net/qq_45689790/article/details/114070956