AT24C02、04、08、16 操作說明


我們這里介紹一下常見的EEPROM,ATMEL的AT24x系列中的AT24C02,學會了這個芯片,其他系列的芯片也是類似的。

AT24C02的存儲容量為2K bit,內容分成32頁,每頁8Byte (共256Byte)。

基礎概念:

  • 存儲容量: 存儲的總數據量

  • 頁:儲存單元的組織方式

  • 尋址方式:訪問元器件的方式,通常計算地址與這個概念有關。

尋址方式

操作時有兩種尋址方式:芯片尋址和片內子地址尋址。

芯片尋址

AT24C02的芯片地址為1010,其地址控制字格式為1 0 1 0 A2 A1 A0 R/W

其中A2,A1,A0代表"可編程地址選擇位"。A2,A1,A0引腳接高/低電平后得到確定的三位編碼,與1010形成7位編碼,即為該器件的地址碼。

R/W為芯片讀寫控制位;該位為0,表示芯片進行寫操作。取決於芯片手冊中的定義,通常,W是低電平有效(0)。

有些大容量的芯片,地址組成位包括了P0P1等選擇位;而這些選擇位實際上是"頁選擇位",用來表示內部地址(如下)。但是實際上原理是類似的。

片內子地址尋址

芯片尋址可對內部 256 Bytes中的任一個進行讀/寫操作,其尋址范圍為00~FF,共256個尋址單位。

該類器件要通過I2C總線操作,讀寫過程中都要先尋址,這類器件地址由兩個字節組成。

如下表,1010是固定的,A表示器件地址,可以拉高和拉低,I2C總線上可以並接2的n次方個器件。P表示具體的內部地址數,比如at24c02共有256個字節,第二個地址字節完全可以滿足,不用P。但是at24c04一個有512個字節,需要9位地址線,第一個字節中的p就表示地址線了,p=0表示低256字節,1表示高256字節。

注意:一般頁寫可以連續寫8個數據。主機每發送一個字節都要接受從機的應答信號。

該類器件是采用I2C總線進行操作的,器件地址根據容量的不同稍有不同,如下:

對於芯片的A0,A1,A2腳:(外部引腳用於芯片尋址,當接入多個IIC設備時,通過引腳電平不同,可以對多個設備進行讀寫操作)

  • 24C01/02:A0,A1,A2都是從設備地址。
  • 24C04,A1,A2是從設備地址,A0變為P0
  • 24C08,A2是從設備地址,A0,A1變為P0、P1
  • 24C16及以上,只有P0、P1、P2

其中,A表示器件地址,P表示頁地址

在讀寫的時候首先是:起始條件+器件地址

器件地址如上所示在16k中,需要兩個字節表示內部地址,正是P 2/1/0 和8位具體的地址

AT24C02/04/08/16 操作說明

另外有關於容量的說明:

  • AT24C01:一共128頁,每頁1字節,共需7位地址數據

  • AT24C02:一共256頁,每頁1字節,共需8位地址數據

  • AT24C04:一共256頁,每頁2字節,共需9位地址數據

  • AT24C08:分4個塊,一共256頁,每頁4字節,共需10位地址數據

  • AT24C16:分8塊,一共256頁,每頁8字節,共需11位地址數據

在讀寫的時候要注意,一般在寫的時候有頁寫,在讀的時候是連續讀,可以設置讀取的個數,根據應答和非應答來結束讀取。

具體的控制時序省略(關鍵在於:理解好地址和儲存單元的計算關系,結合I2C的時序),只是需要注意:

在讀取EEPROM的時候接收到多個數據時,如果不是最后一個數據,單片機要主動發出應答信號,但是接收到最后一個數據后,就不再主動應答,而是等待應答,然后結束條件。

大B與小b之間的換算:

我們常說的MB、KB中的B都是Bytes;但有一些儲存芯片,它們是以Bit作為計量單位的;而 有 8Bit = 1 Byte

因此,小b除以8即可得到大B方式的表示方法。

讀寫操作時序

寫數據

第一步:首先是I2C的起始信號,接着跟上首字節,即EEPROM的地址和讀寫位的組合,讀寫方向上選擇“寫”操作。

第二步:發送要寫入數據的EEPROM內部存儲地址。

第三步:發送要存儲的數據第一個字節、第二個字節… …。

1、寫數據(單片機發送)過程中,每個字節結束后EEPROM都會回應一個“應答位0”,告訴我們寫EEPROM成功,如果沒有應答表示未成功。

2、寫數據過程中,每成功寫入一個字節,EEPROM地址自動加1,當加到最大值,會溢出。

//函數見I2C部分
//向E2PROM中寫入一個字節,addr為字節地址
void E2WriteByte(unsigned char addr,unsigned char dat)
{
	I2CStart();
	I2CWrite(0x50<<1);//尋址后選擇為寫操作
	I2CWrite(addr);	  //寫入存儲地址
	I2CWrite(dat);
	I2CStop();
}

讀數據

第一步:首先是I2C的起始信號,接着跟上首字節,即EEPROM的地址和讀寫位的組合,讀寫方向上選擇“寫”操作。

第二步:發送要讀取的EEPROM內部存儲地址。

第三步:重新發送I2C的起始信號和器件地址,並且在方向位選擇“讀”操作。
(在這三步中,每一個字節實際上都是在“寫”,因此EEPROM都會回應一個“應答位0”。)

第四步:讀取從器件發回的數據,每讀一個字節,如果還想繼續讀下一個字節,就發送一個“應答位0”,如果不想繼續讀了,就發送一個“非應答位1”。

應答位: ACK

非應答位:NACK

//讀取E2PROM中一個字節,addr為字節地址
unsigned cahr E2ReadByte(unsigned char addr)
{
	unsigned char dat;
	I2CStart();
	I2CWrite(0x50<<1);
	I2CWrite(addr);
	I2CStart();
	I2CWrite((0x50<<1)|0x01);
	dat=I2CReadNAK();
	I2CStop();
	return dat;
}

多字節進行讀寫操作

//讀取函數,buf為數據指針,addr為E2中的起始地址,len為讀取長度
void E2Read(unsigned char *buf,unsigned char addr,unsigned char len)
{
		do{
			I2CStart();
			if(I2CWrite(0x50<<1))
			{
				break;
			}
			I2CStop();
		}while(1);//查詢當前是否可以進行讀寫操作
		I2CWrite(addr);
		I2CStart();
		I2CWrite((0x50<<1)|0x01);
		while(len>1)//連續讀取len-1個字節
		{
		   *buf++=I2CReadACK();
		   len--;
		}
		*buf=I2CReadNAK();
		I2CStop();
}
//寫入函數,buf為源數據指針,addr為起始地址,len為寫入長度
void E2Write(unsigned char *buf,unsigned char addr,unsigned char len)
{
	while(len--)
	{
		do{
			I2CStart();
			if(I2CWrite(0x50<<1))
				break;
			I2CStop();
		} while(1);
		I2CWrite(addr++); 
		I2CWrite(*buf++);
		I2CStop();
	}
}

頁寫入功能

一次性寫入一頁,寫完再發送停止位就不用寫完一個字節就檢測一次

連續向頁內寫入幾個字節后,最后發送停止位
E2檢測到停止位,將該頁寫入
如果數據跨頁,則發送一個停止位等待E2空閑后,即上一頁完全寫入非易失區域后,進行下一頁的寫入

void E2Write(unsigned char *buf,unsigned char addr,unsigned char len)
{
	while(len>0)
	{
		do{
			I2CStart();
			if(I2CWrite(0x50<<1))
				break;
			I2CStop();
		} while(1);
		I2CWrite(addr); 
		while(len>0)
		{
			I2CWrite(*buf++);
			len--;
			addr++;
			if((addr&0x07)==0)//檢查地址是否到達頁邊界,每頁8字節,固檢測第三位即可
				break;
		}
		I2CStop();
	}	
}

效率對比

多字節寫入和頁寫入程序都編寫出來了,而且頁寫入的程序我們還特地跨頁寫的數據,它們的寫入時間到底差別多大呢。

我們用一些工具可以測量一下,比如示波器,邏輯分析儀等工具。

我現在把兩次寫入時間用邏輯分析儀給抓了出來,並且用時間標簽 T1 和 T2 標注了開始位置和結束位置,如圖所示,右側顯示的|T1-T2|就是最終寫入 5 個字節所耗費的時間。

多字節一個一個寫入,每次寫入后都需要再次通信檢測 EEPROM 是否在“忙”,因此耗費了大量的時間。

同樣的寫入 5 個字節的數據:

  • 一個一個寫入用了 8.4ms 左右的時間
  • 使用頁寫入,只用了 3.5ms 左右的時間

多字節寫入時間

跨頁寫入時間

附錄:關於IIC-EEPROM頁寫問題

結論:無論從什么地址開始連續寫,不能超過(跨過)一整頁。

背景:

在向 EEPROM 連續寫入多個字節的數據時,如果每寫一個字節都要等待的話,整體上的寫入效率就太低了。因此 EEPROM 的廠商就想了一個辦法,把 EEPROM 分頁管理。24C01、24C02 這兩個型號是 8 個字節一個頁,而 24C04、24C08、24C16 是 16 個字節一頁。例如AT24C02,一共是 256 個字節,8 個字節一頁,那么就一共有 32 頁。

分配好頁之后,如果我們在同一個頁內連續寫入幾個字節后,最后再發送停止位的時序。EEPROM 檢測到這個停止位后,就會一次性把這一頁的數據寫到非易失區域,就不需要像上節課那樣寫一個字節檢測一次了,並且頁寫入的時間也不會超過 5ms。如果我們寫入的數據跨頁了,那么寫完了一頁之后,我們要發送一個停止位,然后等待並且檢測 EEPROM 的空閑模式,一直等到把上一頁數據完全寫到非易失區域后,再進行下一頁的寫入,這樣就可以在很大程度上提高數據的寫入效率。

本質:頁寫的原理是通過內部寫緩沖RAM實現的(讀操作不需要,可以連續讀)。

詳解:

AT24CXX系列的EEPROM為了提高寫效率,提供了頁寫功能。

內部有個一頁大小的寫緩沖RAM(地址范圍也就是從00到頁大小)。

發生寫操作時,開始送入的地址對應的頁被選中,並將其內容映像到緩沖RAM,數據從低端地址對應的緩沖RAM地址開始修改,超過這個地址范圍就回到00。

寫完后,就會把開始確定的EEPROM頁擦除,再把一整頁RAM數據寫入。所有寫數據都發生在開始寫地址時確定的頁上。

如,頁容量為128,一頁都是從00開始按128字節分成一個個的頁;

此時,0頁就是07F,1頁就是80FF,類推,邊界就是128字節的整數倍地址。

頁RAM的地址范圍為7位00~7F,寫入時高端地址就是頁號。

發生寫操作,開始送入的地址對應的頁被鎖存,后續不論寫多少,都在這個頁中,只是一個頁內的地址進行加一,超過就歸零開始。從F0開始寫32個字節,那么開始送入的地址為F0,就會鎖定在1號頁(第2個頁)上,底端7位頁內部地址開始從70H開始寫,到達7F時回到00再到10H,也就是寫在了F0FF,808F。

也就是,從01開始寫也只能到7F,再往80寫就跑到00上去了,這就是寫操作的翻卷,datasheet上都有說明。

就是從邊界前寫兩個字節也要分兩次寫。頁是絕對的,按整頁大小排列,不是從開始寫入的地址開始算。

讀沒有頁的問題,可以從任意地址開始讀取任意大小數據,只是超過整個存儲器容量時地址才回卷。但一次性訪問的數據長度也不要太大。

所以,使用分頁的存儲器進行儲存時,要做好存儲管理,盡量同時讀寫的數據放在一個頁上。

ref :


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM