天天看點

EEPROM IIC

1. 資料位的有效性規定

I2C總線進行資料傳送時,時鐘信号為高電平期間,資料線上的資料必須保持穩定,隻有在時鐘線上的信号為低電平期間,資料線上的高電平或低電平狀态才允許變化

EEPROM IIC

2. 起始和終止信号

SCL線為高電平期間,SDA線由高電平向低電平的變化表示起始信号;SCL線為高電平期間,SDA線由低電平向高電平的變化表示終止信号

EEPROM IIC

起始和終止信号都是由主機發出的,在起始信号産生後,總線就處于被占用的狀态;在終止信号産生後,總線就處于空閑狀态

接收器件收到一個完整的資料位元組後,有可能需要完成一些其它工作,如處理内部中斷服務等,可能無法立刻接收下一個位元組,這時接收器件可以将SCL線拉成低電平,進而使主機處于等待狀态。直到接收器件準備好接收下一個位元組時,再釋放SCL線使之為高電平,進而使資料傳送可以繼續進行

3. 資料傳送格式

每一個位元組必須保證是8位長度。資料傳送時,先傳送最高位(MSB),每一個被傳送的位元組後面都必須跟随一位應答位(即一幀共有9位)

EEPROM IIC

主機向從機發送資料:

有陰影部分表示資料由主機向從機傳送,無陰影部分則表示資料由從機向主機傳送

A表示應答, Â非表示非應答。S表示起始信号,P表示終止信号

EEPROM IIC

主機在第一個位元組後,立即從從機讀資料:

EEPROM IIC

改變傳送方向:

在傳送過程中,當需要改變傳送方向時,起始信号和從機位址都被重複産生一次

EEPROM IIC

4. 總線的尋址

EEPROM IIC

D7~D1位組成從機的位址。D0位是資料傳送方向位,為“0”時表示主機向從機寫資料,為“1”時表示主機由從機讀資料

主機發送位址時,總線上的每個從機都将這7位位址碼與自己的位址進行比較,如果相同,則認為自己正被主機尋址,根據R/T位将自己确定為發送器或接收器

一個從機的7位尋址位有4位是固定位,3位是可程式設計位,這時僅能尋址8個同樣的器件,即可以有8個同樣的器件接入到該I2C總線系統中

5. 信号模拟

EEPROM IIC

起始信号:

void I2CStart(void)
{       
	SDA = 1;
	SomeNop();
	SCL = 1;
	SomeNop();
	SDA = 0;
	SomeNop();
}
           

終止信号:

void I2CStop(void)
{       
	SDA = 0;
	SomeNop();
	SCL = 1;
	SomeNop();
	SDA = 1;
	SomeNop();
}
           

6. 串行E2PROM

寫入過程:

EEPROM IIC

讀出過程:

EEPROM IIC

7. 引腳說明

EEPROM IIC

A0、A1、A2均為0

EEPROM IIC
EEPROM IIC
EEPROM IIC

是以從機位址的7位資料為:0xa0

8. 總線時序

EEPROM IIC

9. 舉例

單片機小精靈:

http://download.csdn.net/download/zhangxuechao_/9894028

void delay10us(void)   //誤差 0us
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=2;a>0;a--);
}	

//IIC起始
void i2cStart()
{
	SDA = 1;
	delay10us();
	SCL = 1;
	delay10us();
	SDA = 0;
	delay10us();
	SCL = 0;
	delay10us();
		   
	return;
}		  

//IIC停止
void i2cStop()
{
	SDA = 0;
	delay10us();
	SCL = 1;
	delay10us();
	SDA = 1;
	delay10us();
		   
	return;
}

//IIC發送
u8 i2cSend(u8 d)
{
	u8 i = 0, j = 0;
	for(i = 0; i < 8; i++)
	{
		SDA = d >> 7;
		d = d << 1;
		delay10us();
		SCL = 1;
		delay10us();
		SCL = 0;
	}

	SDA = 1;
	delay10us();
	SCL = 1;

	while(SDA)
	{
		if(j++ > 200)
		{
			SCL = 0;
			delay10us();
			return 0;
		}
	}

	SCL = 0;
	delay10us();

	return 1;
}	 

//IIC接收
u8 i2cRecv()
{
	u8 i = 0, d = 0;
	for(i = 0; i < 8; i++)
	{
		SCL = 1;
		delay10us();
		d <<= 1;
		d |= SDA;
		delay10us();
		SCL = 0;
		delay10us(); 
	}

	return d;
}

//E2PROM寫
void at24c02Write(u8 addr, u8 d)
{
	i2cStart();
	i2cSend(0xa0);
	i2cSend(addr);
	i2cSend(d);
	i2cStop();	
}

//E2PROM讀
u8 at24c02Read(u8 addr)
{
	u8 d = 0;

	i2cStart();
	i2cSend(0xa0);
	i2cSend(addr);
	i2cStart();
	i2cSend(0xa1);
	d = i2cRecv();
	i2cStop();
	
	return d;	
}