詳解數據存儲芯片AT24C02的應用及編程

一.芯片簡介

AT24C02是一個2K位串行CMOS E2PROM,內部含有256個8位字節,採用先進CMOS技術實質上減少了器件的功耗。AT24C02有一個8字節頁寫緩衝器,該器件通過IIC總線接口進行操作,有一個專門的寫保護功能。

二.芯片參數

1.特點
  • 工作電壓:1.8V~5.5V;
  • 低功耗CMOS技術,工作電流1mA,待機電流1uA;
  • 應用在內部結構:128x8(1K),256x8(2K),512x8(4K),1024x8(8K),2048x8(16K);
  • 二線串行接口,支持標準IIC通信協議;
  • 雙向數據傳輸協議;
  • 兼容 400KHz傳輸速率(1.8V,2.5V,2.7V,3.6V);
  • 支持硬件寫保護功能;
  • 擦出次數可達10000次;
  • 存儲數據時間超過100年;
2.引腳定義

在這裏插入圖片描述
A0-A2引腳爲芯片地址,用於多器件工作模式;SDA、SCL分別爲IIC通信的數據線和時鐘線;WP爲寫保護引腳,當該引腳接 GND 時,允許正常的讀/寫操作。當該引腳接 VCC 時,芯片啓動寫保護功能;

3.參考電路

在這裏插入圖片描述
A0-A2接到GND上,地址固定爲0;SCL、SDA引腳內部爲開漏輸出,所以需接上拉電阻;WP引腳接GND,表示芯片可讀可寫。

三.通信接口

1.芯片讀寫地址

在進行I2C通信時,主機發送啓動信號後,再發送尋址信號。器件的地址有7位和10位,以7爲地址尋址爲例,尋址信號由一個字節構成,高7位爲地址位,最低位爲方向位,用來表示主機與從器件的數據傳輸方向;方向位0代表主機接下來對從器件進行寫操作;方向位爲1,表明主機接下來對器件進行讀操作。
在這裏插入圖片描述
如上圖,AT24C02的高4位是固定的,爲1010b,低3位則由A0/A1/A2信號線的電平決定。按照我們此處的連接, A0/A1/A2 均爲 0,所以 EEPROM 的 7 位設備地址是: 1010 000b ,即 0x50。
由於 I2C 通訊時常常是地址跟讀寫方向連在一起構成一個 8 位數,且當R/W 位爲 0 時,表示寫方向,所以加上 7 位地址,其值爲“ 0xA0”,常稱該值爲 I2C 設備的“寫地址”;當 R/W 位爲 1 時,表示讀方向,加上 7 位地址,其值爲“ 0xA1”,常稱該值爲“讀地址”。
A0/A1/A2輸入腳用於多個器件級聯時設置器件地址,當這些腳懸空時默認值爲0。當使用AT24C02 時最大可級聯8個器件。如果只有一個AT24C02被總線尋址,這三個地址輸入腳(A0、A1、A2 )可懸空(接地也可以)或連接到Vss,如果只有一個AT24C01被總線尋址這三個地址輸入腳(A0、A1、A2 )必須連接到Vss。

2.IIC通信

由於51單片機內部無集成IIC控制硬件資源,所以需要軟件模擬IIC通信。函數有四個,分別爲IIC起始信號、IIC停止信號、IIC讀取字節、IIC寫入字節等函數。

/*********************IIC.h*************************************/
//--定義使用的IO口--//
sbit I2C_SCL = P2^1;
sbit I2C_SDA = P2^0;

//--聲明全局變量--//
void I2C_Delay10us();
void I2C_Start();           //起始信號:在I2C_SCL時鐘信號在高電平期間I2C_SDA信號產生一個下降沿
void I2C_Stop();            //終止信號:在I2C_SCL時鐘信號高電平期間I2C_SDA信號產生一個上升沿
uchar I2C_SendByte(uchar dat, uchar ack);//使用I2c讀取一個字節
uchar I2C_ReadByte();       //通過I2C發送一個字節。在I2C_SCL時鐘信號高電平期間,保持發送信號I2C_SDA保持穩定

/*********************IIC.c*************************************/

//延時:1us
void I2C_Delay10us()
{
	uchar a, b;
	for(b=1; b>0; b--)
	{
		for(a=2; a>0; a--);
	}
}

// 起始信號:在I2C_SCL時鐘信號在高電平期間I2C_SDA信號產生一個下降沿
void I2C_Start()
{
	I2C_SDA = 1;
	I2C_Delay10us();
	I2C_SCL = 1;
	I2C_Delay10us();//建立時間是I2C_SDA保持時間>4.7us
	I2C_SDA = 0;
	I2C_Delay10us();//保持時間是>4us
	I2C_SCL = 0;			
	I2C_Delay10us();		
}

//終止信號:在I2C_SCL時鐘信號高電平期間I2C_SDA信號產生一個上升沿
void I2C_Stop()
{
	I2C_SDA = 0;
	I2C_Delay10us();
	I2C_SCL = 1;
	I2C_Delay10us();//建立時間大於4.7us
	I2C_SDA = 1;
	I2C_Delay10us();		
}

//通過I2C發送一個字節。在I2C_SCL時鐘信號高電平期間, 保持發送信號I2C_SDA保持穩定
uchar I2C_SendByte(uchar dat, uchar ack)
{
	uchar a = 0,b = 0;//最大255,一個機器週期爲1us,最大延時255us。			
	for(a=0; a<8; a++)//要發送8位,從最高位開始
	{
		I2C_SDA = dat >> 7;	 //起始信號之後I2C_SCL=0,所以可以直接改變I2C_SDA信號
		dat = dat << 1;
		I2C_Delay10us();
		I2C_SCL = 1;
		I2C_Delay10us();//建立時間>4.7us
		I2C_SCL = 0;
		I2C_Delay10us();//時間大於4us		
	}
	I2C_SDA = 1;
	I2C_Delay10us();
	I2C_SCL = 1;
	while(I2C_SDA && (ack == 1))//等待應答,也就是等待從設備把I2C_SDA拉低
	{
		b++;
		if(b > 200)	 //如果超過200us沒有應答發送失敗,或者爲非應答,表示接收結束
		{
			I2C_SCL = 0;
			I2C_Delay10us();
			return 0;
		}
	}
	I2C_SCL = 0;
	I2C_Delay10us();
 	return 1;		
}

// 使用I2c讀取一個字節
uchar I2C_ReadByte()
{
	uchar a = 0,dat = 0;
	I2C_SDA = 1;			//起始和發送一個字節之後I2C_SCL都是0
	I2C_Delay10us();
	for(a=0; a<8; a++)//接收8個字節
	{
		I2C_SCL = 1;
		I2C_Delay10us();
		dat <<= 1;
		dat |= I2C_SDA;
		I2C_Delay10us();
		I2C_SCL = 0;
		I2C_Delay10us();
	}
	return dat;		
}

三.控制程序

實現了基本IIC通訊函數後,就可對AT24C02進行操作,主要是寫入數據和讀取數據兩個函數。
芯片尋址可對內部256B中的任一個進行讀/寫操作,其尋址範圍爲00FF,共256個尋址單位。所以可任意在00FF地址寫入我們需要保存的數據。

1.AT24C02寫入數據

時序順序爲:發送開始信號,IIC啓動->發送器件地址,其中讀寫標誌位爲寫->發送器件內部存儲地址->向器件中寫入數據->發送停止信號,IIC停止;

//函數功能		   : 往24c02的一個地址寫入一個數據

void At24c02Write(unsigned char addr,unsigned char dat)
{
	I2C_Start();
	I2C_SendByte(0xa0, 1);//發送寫器件地址
	I2C_SendByte(addr, 1);//發送要寫入內存地址
	I2C_SendByte(dat, 0);	//發送數據
	I2C_Stop();
}
2.AT24C02讀取數據

時序順序爲:發送開始信號,IIC啓動->發送器件地址,其中讀寫標誌位爲寫->發送器件內部->發送開始信號,IIC再次啓動->發送器件地址,其中讀寫標誌位爲讀->從器件讀出數據->返回所讀取的數據;

// 讀取24c02的一個地址的一個數據

unsigned char At24c02Read(unsigned char addr)
{
	unsigned char num;
	I2C_Start();
	I2C_SendByte(0xa0, 1); //發送寫器件地址
	I2C_SendByte(addr, 1); //發送要讀取的地址
	I2C_Start();
	I2C_SendByte(0xa1, 1); //發送讀器件地址
	num=I2C_ReadByte(); //讀取數據
	I2C_Stop();
	return num;	
}
3.AT24C02讀寫數據

實現以上的讀寫功能,就可以使用AT24C02來實現我們需要的功能。功能爲:使用按鍵1,寫入num0;按鍵2,讀取num0;按鍵3,使num0加1;按鍵4,清零num0;

void main()
{
	unsigned int num0 = 0,num1 = 0,num2 = 0,n;

	LcdInit();
	while(1)
	{
		if(K1 == 0)		 //按鍵1按下,將num0寫入eeprom
		{
			Delay10ms(1);
			if(K1 == 0)
				{At24c02Write(2,num0);
				At24c02Write(3,num0);}
			while((n < 20)&&(K3==0))
			{
				n++;
				Delay10ms(1);	
			}			
			n=0;
			n=0;
		}
		
		if(K2 == 0)		 //按鍵2按下,讀取eeprom數據
		{
			Delay10ms(1);
			if(K2 == 0)
				{num1 = At24c02Read(2);
				num2 = At24c02Read(3);	}
			while((n < 20)&&(K2 == 0))
			{
				n++;
				Delay10ms(1);	
			}			
			n=0;
		}			
		if(K3 == 0)		 //按鍵3按下,使num0自加1
		{
			Delay10ms(1);
			if(K3 == 0)
				num0++;
			while((n < 50)&&(K3 == 0))
			{
				n++;
				Delay10ms(1);	
			}			
			n=0;
			if(num0==256)
				num0=0;
		}
			
		if(K4 == 0)		 //按鍵4按下,清零
		{
			Delay10ms(1);
			if(K4 == 0)
				num0 = 0;
			while((n < 50) && (K4 == 0))
			{
				n++;
				Delay10ms(1);	
			}			
			n=0;
		}
		LCD_Display();	
	}
}								

如需AT24C02相關資料及例程, 請關注公衆號,首頁回覆AT24C02獲取資料
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章