1. 程式人生 > >貳拾壹:EPPROM的操作

貳拾壹:EPPROM的操作

#EEPROM概述 電可擦除只讀儲存器 EEPROM 可以長期非易失地儲存資訊,又可以隨時用電改寫。EEPROM的種類很多,它們大致可以分為並行、序列、加密型3種。

  1. 並行 EEPROM:速度快,可做到高度整合。但是引腳多,使用不方便。
  2. 序列 EEPROM:引腳少,應用方便。但結構複雜,難以做到了高度整合,所以微控制器一般容量不大。
  3. 加密型 EEPROM:可以對寫入的資料進行加密,避免越權存取,保密功能強。但加密型EEPROM的操作步驟比較複雜,成本高。

這裡寫圖片描述

#通訊時序

這裡寫圖片描述 1.起停訊號 時鐘線保持高電平期間,資料線電平從高到低的跳變為I2C匯流排的起始訊號。時鐘線保持高電平期間,資料線電平從低到高的跳變為I2C匯流排的停止訊號。 2.裝置選址 主器件通過傳送1個起始訊號啟動傳送過程,然後傳送它所需要定址的從器件地址,8位從器件地址的高4位固定為1010,接下來的3位(A10,A9,A8)為器件的地址位。 3.應答訊號 I2C匯流排傳送資料時,每成功傳送1Byte,接收器都必須產生1個應答訊號,應答的器件在第9個時鐘週期將SDA線拉低表示其已收到1個8位資料。

#寫操作 1.位元組寫 這裡寫圖片描述

2.頁寫(一頁,即16Byte,16個位元組) 這裡寫圖片描述 #讀操作 1.從當前地址讀 這裡寫圖片描述 2.隨機地址讀 這裡寫圖片描述

#實驗 這裡寫圖片描述 #程式碼

	
*   【課程22】 ****EEPROM的讀寫***********
*
*   【說  明】 ****使用CAT24WC16晶片,掉電資料非易失
*		
*   【描  述】 ****往CAT24WC16晶片寫入一個數據後,然後再從同一個
				地址取出資料,看兩個資料是否相等?
*
******************************************************************/

#include<reg52.h>
#include <intrins.h>

//---------常用的兩個巨集定義-------------- 
#define uint8	unsigned char
#define uint16  unsigned int


/*--24WC16功能引腳設定-----*/
sbit  WC16_SCL=P2^2;
sbit  WC16_SDA=P2^3;


/********************************************************
** 名稱 :void DelayMS(uint16 dly)
** 功能 :毫秒級延時(24M的晶振)
** 入口引數 :dly
					使用者的延時引數   
** 出口引數 :無   
*********************************************************/
void DelayMS(uint16 dly)
{
	uint16 x,y;
	for(x=dly;x>0;x--)
		for(y=247;y>0;y--);
}


/********************************************

功能:短延時函式,保持時鐘的電平訊號
*********************************************/
void nNop()
{
	uint8 i;
	for(i=0;i<15;i++);
}

/********************************************
函式名:IIC_Start()
功能:匯流排協議的起始訊號
備註:Scl=1期間,資料線(Sda)電平從高到低的跳
			變作為I2C 匯流排的起始訊號
**********************************************/
void IIC_Start()
{	   	
	WC16_SDA=1;
	nNop();
	WC16_SCL=1;
	nNop();
	WC16_SDA=0;
	nNop();
	WC16_SCL=0;
}

/********************************************
函式名:IIC_Stop()
功能:匯流排協議的停止訊號 
備註:Scl=0期間,資料線(Sda)電平從低到高的跳
		變作為I2C 匯流排的停止信  號        
**********************************************/
void IIC_Stop()
{
	 WC16_SDA=0;
	 nNop();
	 WC16_SCL=1;
	 nNop();
	 WC16_SDA=1;
	 nNop();
}


/********************************************
函式名:WC16Data_Write(uint8 temp)
功能:匯流排寫資料.地址函式         
入口引數:temp 為要寫的資料或地址    
**********************************************/
void WC16Data_Write(uint8 temp)
{
	 uint8 i;
	 WC16_SCL=0;
	 for(i=0;i<8;i++)
		{
		 	WC16_SDA=(bit)(temp&0x80);  //實現從高位到低位傳遞  
		 	temp=temp<<1;
		 	nNop();
		 	WC16_SCL=1;
		 	nNop();
		 	WC16_SCL=0;
		}
	 nNop();
	 WC16_SCL=1;
	 while(WC16_SDA);  //當WC16_SDA 為低時為 從機的應答訊號 
	 nNop();
	 WC16_SCL=0;
}



/********************************************
函式名: WC16Data_Read(void)
功能:匯流排讀資料函式      
出口引數:temp 為要讀的資料  
**********************************************/

 WC16Data_Read(void)
{
	 uint8 i,temp=0;
	 for(i=0;i<8;i++)
	{
		 WC16_SCL=0;
		 WC16_SDA=1;
		 nNop();
		 WC16_SCL=1;
		 nNop();
		 temp=(temp<<1)|WC16_SDA;	//八次迴圈讀出EEPROM中的數,放入temp變數中
	}
	WC16_SCL=0;
	nNop();
	WC16_SDA=1;   //讀完資料後主機發給從機的非應答訊號 
	nNop();
	WC16_SCL=1;
	WC16_SCL=0;
	return(temp);
}
/********************************************
函式名:WC16Data_Put(uint8 sla,uint8 slaaddr,uint8 Data) 
功能:按照匯流排協議,  微控制器將資料寫進rom指定地址
入口引數:uint8 sla
		  uint8 slaaddr
	  	  uint8 Data
出口引數:無
**************************************************/
WC16Data_Put(uint8 sla,uint8 slaaddr,uint8 Data)
{
	 IIC_Start();
	 WC16Data_Write(sla);  //sla為 從地址+R/W 
	 WC16Data_Write(slaaddr);// slaaddr為從地址
	 WC16Data_Write(Data);  //Data為要寫的資料
	 IIC_Stop();
}


/********************************************
函式名:WC16Data_Rev(uint8 sla,uint8 slaaddr,uint8 Data) 
功能:按照匯流排協議,微控制器在指定地址讀資料
入口引數:uchar sla   
		  uchar slaaddr
出口引數:無
**************************************************/
WC16Data_Rev(uint8 sla,uint8 slaaddr)
{
	 uint8 temp;
	 IIC_Start();
	 WC16Data_Write(sla);
	 WC16Data_Write(slaaddr);
	 IIC_Start();
	 WC16Data_Write(sla+1);
	 temp=WC16Data_Read();
	 IIC_Stop();
	 return(temp);
}

void  main()
{
	uint8 temp=0;
	WC16_SDA=1;   //對兩功能引腳進行初始化
	WC16_SCL=1;
	WC16Data_Put(0xa0,0x00,0x55);
	DelayMS(50);				//此延時非常重要,資料寫進EEPROM後要延遲一段時間才能進行讀。
	temp=WC16Data_Rev(0xa0,0x00);
	while(1)
	{		
		P0 = temp;
		DelayMS(5000);
	}
}