一、EEPROM是什么
eeprom是帶電可擦可編程只讀存儲器。
EEPROM (Electrically Erasable Programmable read only memory)是指帶電可擦可編程只讀存儲器。是一種掉電后數據不丟失的存儲芯片。 EEPROM 可以在電腦上或專用設備上擦除已有信息,重新編程。一般用在源即插即用。
二、IIC串行總線的組成及工作原理
2.1、IIC串行總線的組成及其工作原理
采用串行總線的組成及其工作原理
采用串行總線技術可以使用系統的硬件設計大大簡化、系統的體積減小、可靠性提供。同時系統的更改和擴充極為容易。
常用的串行擴展總線有:IIC(Intet IC BUS)總線、單總線(1-WIRE BUS)、SPI(Serial Peripheral Interface)總線、Microwire/PLUS等。
2.2、IIC串行總線概述
IIC總線是PHLIPS公司推出的一種串行總線,是具備多主機系統所需的包括總系裁決和高低速器件同步功能的高性能串行總線。
每個接到IIC總線的器件都有唯一的地址。主機與其他器件之間的數據傳送可以是由主機發送數據到其他器件,這時主機即為發送器。由總線上接收數據的器件則為接收器。
在多主機系統中,可能同時由幾個主機企圖啟動總線傳送數據,為了避免混亂,IIC總線要通過總線仲裁,以決定由哪一臺主機控制總線。
在80C51單片機應用系統的串行總線擴展中,我們經常遇到的是以80C51單片機為主機,其他接口器件為從機的單主機情況。
2.3、IIC總線的數據傳送
2.3.1、數據位的有效性規定
IIC總線進行數據傳送時,時鐘信號(SCL)為高電平期間,數據線(SDA)上的數據必須保持穩定,只有在時鐘線上的信號為低電平期間,數據線上的高電平或低電平狀態才允許變化。
2.3.2、起始和終止信號
SCL(時鐘線)線為高電平期間,SDA(數據線)線由高電平向低電平的變化表示起始信號;SCL(時鐘線)線為高電平期間,SDA線由低電平向高電平的變化表示終止信號。
起始信號都是由主機發出的,在起始信號產生后,總線就處于別占用的狀態;在終止信號產生后,總線就處于空閑狀態。
連接到IIC總線上的期間,若具有IIC總線的硬件的接口,則容易檢測到起始信號和終止信號。
接收器件收到一完整的數據字節后,有可能需要完成一些其他工作,如處理內部中斷服務等,可能無法立刻接收下一個字節,這時接收器件可以將SCL線拉成低電平,從而使主機處于等待狀態,直到接收器準備好接收下一個字節時,再釋放SCL線使之為高電平,從而使數據傳送可以繼續進行。
2.3.3、數據傳送格式
(1)字節傳送與應答
每一個字節必須保證是8為長度。數據傳送時,先傳送最高位(MSB),每一個被傳送的字節后面都必須跟隨一位應答位(即一幀共有9位)
由于某種原因從機不對主機尋址信號應答時(如從機正在進行實時性的處理工作而無法接收總線上的數據),它必須將數據線置于高電平,而由主機產生一個終止信號以結束總線的數據傳送。
如果從機對主機進行了應答,但在數據傳送一段時間后無法繼續接收更多的數據時,從機可以通過對無法接收的第一個數據字節“非應答”通知主機,主機則應發出終止信號以結束數據的繼續傳送。
當主機接收數據時,它接收到最后一個數據字節后,必須從主機發出一個結束傳送的信號。這個信號是由對從機的“非應答”,來實現的,然后,從機釋放SDA線,以允許主機產生終止信號。
(2)數據幀格式
IIC總線上傳送的數據信號是廣義的,既包括地址信號,又包括真正的數據信號。
在起始信號后必須傳送一個從機的地址(7位),第8位是數據的傳送方向位(R/T),用“0”表示主機發送數據(T),"1"表示主機接收到數據(R)。每次數據傳送總是主機產生的終止信號結束。但是,若主機希望繼續占用總線進行新的數據傳送,則可以不產生終止信號,馬上再次發送出起始信號對另外一從機進行尋址。
在總線的一次數據傳送過程中,可以有以下幾種組合方式:
a、主機向從機發送數據,數據傳送方向在整個傳送過程中不變:
b、主機在第一個字節后,立即從從機讀數據
c、在數據傳送過程中,當需要改變傳送方向時,起始信號和從機地址都被重復產生一次,但兩次讀/寫方向位正好反相。
三、總線尋址
3.1、總線尋址過程
IIC總線協議有明確的規定:采用7位的尋址字節(尋址字節是起始信號的第一個字節)。
(1)尋址字節的位定義
D7~D1位組成從機尋址地址。D0位是數據傳送方向位,為"0"表示主機向從機寫數據,為“1”從機向主機讀數據。
主機發送地址:總線上的每個從機都將這7位地址碼與自己的地址進行比較,如果相同則認為正被主機尋址,根據R/T位將自己確定為發送器或接收器
從機的地址由固定部分和可編程部分組成,在一個系統中可能希望接入多個相同的從機,從機地址中可編程部分決定了可接入總線該類器件的最大數目,如一個從機的7位尋址位有4位是固定的,3位是可編程位,這時僅能尋址8個同樣的器件,即可以有8個同樣的器件接入到該IIC總線系統中。
3.2、80C51單片機IIC串行總線器件的接口
總線數據傳送的模擬
主機可以采用不帶IIC總線接口的單片機,如80C51,AT89C2051等單片機,利用軟件實現IIC總線的數據傳送,即軟件與硬件的結合是信號的模擬。
(1)、典型信號模擬
為了保證數據傳送的可靠性,標準的IIC總線的數據傳送有嚴格的時序要求。IIC總線的起始信號,終止信號,發送信號,發送"0"以及“1”的模擬時序
(2)、典型信號模擬子程序
// 起始信號
void 12cStart(void)
{
SDA=1;
SomeNop();
SCL=1;
SomeNop():
SAD=0;
}
// 終止信號
void 12cStop(void)
{
SDA =0;
SomeNop();
SCL=1;
SomeNop();
SDA=1;
SomeNop();
}
3.3、IIC總線器件的擴展
(1)、擴展電路
(2)、串行EEPROM的擴展
1、串行EEPROM典型產品
ATMEL公司的AT24C系列:
AT24C01:128字節(128 * 8位);
AT24C02:256字節(256 *8位);
AT24C04:512字節(512 * 8);
AT24C08:1K字節(1K * 8位);
AT24C16:2K字節(2K * 8位);
2、寫入過程
AT24C系列EEPROM芯片地址的固定部分分為1010,A2,A1,A0引腳接高、低電平后得到確定的3位編碼。形成的7位編碼即為該器件的地址碼。
單片機進行寫操作時,首先發送該器件的7位地址碼和寫方向位“0”(共8位,即為一個字節),發送完后釋放SDA線并在SCL線上產生第9個時鐘信號。被選中的存儲器器件在確認是自己的地址后,在SDA線上產生一個應答信號作為響應,單片機收到應答后就可以傳送數據了。
傳送數據時,單片機首先發送一個字節的被寫入器件的存儲區的首地址,收到存儲器器件的應答后,單片機就逐個發送各數據字節,但每個發送一個字節后都要等待應答。
AT24C系列器件片內地址在接收到每一個數據字節地址后自動加1,在芯片的“一次裝載字節數”(不同芯片字節數不同)限度內,只需要輸入首地址,裝載字節數不超過芯片的“一次裝載字節數”時,數據地址將“上卷”,前面的數據將被覆蓋。
當要寫入的數據傳送完后,單片機應發出終止信號以結束寫入操作。寫入n個字節的數據格式:
3、讀出的過程
單片機先發送該器件的7位地址和寫方向位“0”("偽寫"),發送完后釋放SDA線并在SCL線上產生第9個時鐘信號,被選中的存儲器器件在確認是自己的地址后,在SDA線上產生一個應答信號作為回應。
然后,再發送一個字節的要讀出器件的存儲區的首地址,收到應答后,單片機要重復一次起始信號并發出器件地址和讀方位("1"),收到器件應答后就可以讀出數據字節,每讀出一個字節,單片機都要回復應答信號,當最后一個字節數據讀取完畢后,單片機應返回以“非應答”(高電平),并發出終止信號以結束讀出操作。
四、移位操作
左移時最低補位0,最高位移入PSW的CY位。
右移時最高位保持原數,最低位移除。
五、AT24CXX存儲器工作原理
5.1、特點
與400KHZ,IIC總線兼容
1.8到6.0伏工作電壓范圍
低功耗CMOS技術
寫保護功能當wp為高電平時進入寫保護狀態
頁寫緩沖器
自定義擦寫周期
100萬次編程/擦除周期
可保存數據100年
9腳DIP SOIC或TSSOP封裝
溫度范圍商業級和工業級
5.2、概述
CAT24WC01/02/04/08/16是一個1k/2k/4k/8k/16k位串行COMS,EEPROM內部含有128/256/512/1024/2048個8位字節CATALYST公司的先進COMS技術實質上減少了器件的功耗,CAT24W01有一個8字節寫緩沖器CAT24W02/04/08/16字節頁寫緩沖器,該器件通過IIC總線接口進行操作有一個專門的寫保護功能。
5.3、引腳說明
5.4、總線時序
5.5、讀寫周期范圍
期范圍
5.6、硬件設計
六、軟件設計
6.1、main.c
/*待實現的功能:通過單片機的獨立按鍵,實現讀寫操作 在數碼管上顯示*/
#include "reg52.h" //此文件中定義了單片機的一些特殊功能寄存器
#include "I2C.h"
typedef unsigned int u16;
typedef unsigned char u8;
// 位定義 獨立按鍵
sbit k1 = P3^1; // 獨立按鍵
sbit k2 = P3^0;
sbit k3 = P3^2;
sbit k4 = P3^3;
// 位定義38譯碼器 端口
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
char num=0;
u8 disp[4];
// 數碼管的斷選數據 顯示0~9
u8 code smgduan[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
// 延時函數
void delay(u16 i)
{
while(i--);
}
// 按鍵處理函數
void Keypros()
{
if(k1==0)
{
delay(1000); // 按鍵消抖處理
if(k1==0) // 當k1等于0(k1低電平)
{
At24c02Write(1,num); // 調用At24c02Write()函數 在地址1內容寫入數據num
}
while(!k1);
}
if(k2==0) // 當k2等于0(k2低電平)
{
delay(1000);
if(k2==0)
{
num=At24c02Read(1); // 讀取EEPROM地址內的數據保存在num中
}
while(!k2);
}
if(k3==0)
{
delay(100);
if(k3==0)
{
num++; // 數據加1
if(num>255)num=0;
}
while(!k3);
}
if(k4==0)
{
delay(1000); //消抖處理
if(k4==0)
{
num=0; //數據清零
}
while(!k4);
}
}
// 數據處理函數
void datepros()
{
disp[0]=smgduan[num/1000]; // 千位
disp[1]=smgduan[num%1000/100]; // 百位
disp[2]=smgduan[num%1000%100/10]; // 十位
disp[3]=smgduan[num%1000%100%10]; // 各位
}
// 數碼管顯示函數
void DigDisplay()
{
u8 i;
for(i=0;i<4;i++)
{
switch(i) // 位選
{
case(0):
LSA=1;LSB=1;LSC=0;break;// 顯示第0位
case(1):
LSA=0;LSB=1;LSC=0;break;// 顯示第1位
case(2):
LSA=1;LSB=0;LSC=0;break;
case(3):
LSA=0;LSB=0;LSC=0;break;
}
P0=disp[i];// 發送數據
delay(100); // 間隔一段時間
P0=0x00;// 消隱
}
}
void main()
{
while(1)
{
Keypros();
datepros();
DigDisplay();
}
}
6.2、I2C.c
#include "i2c.h"
// 延遲函數
void Delay10us(void) // 延遲10us 誤差 0us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
// 起始信號
void I2cStart()
{
SDA=1; // 高電平1
Delay10us(); // 持續時間 > 4.7us
SCL=1; // 高電平1
Delay10us(); // 持續時間 > 4.7us
SDA=0; // 低電平 0
Delay10us(); // 持續時間 > 4us
SCL=0; // 低電平 0
Delay10us(); // 持續時間 > 4us
}
// 終止信號
void I2cstop()
{
SDA=0; // 低電平
Delay10us(); // 持續時間 > 4us
SCL=1; // 高電平
Delay10us(); // 持續時間 > 4.7us
SDA=1; // 高電平
Delay10us(); // 持續時間 > 4.7us
}
// 發送字節函數 先發送高位 在發送低位
unsigned char I2cSendByte(unsigned char dat)
{
unsigned char a=0,b=0; // 最大255,一個機器周期為1us,最大延時255us。
for(a=0;a<8;a++) // 發送字節 最高位開始發送
{
/*位移操作
左移時最低位補0,最高位移入PSW的CY位
右移時最高位保持原數,最低位移除
*/
/*dat>>7就是dat這么一個字節總共8個位的數據向右移7個位,原來的最高位就移到了最右的位置,左邊7個位全被抹成0,
SDA=dat>>7實際也就是取得了原先最高位的值了。
舉例:
D7 D6 D5 D4 D3 D2 D1 D0
1 0 1 0 0 0 1 1
SDA =dat >> 7 數據右移7位,原來的最高位就移到了最右的位置,左邊7個位全被抹成0 只剩D7賦值給SDA 變為:
D0 D1 D2 D3 D4 D5 D6 D7
0 0 0 0 0 0 0 1
*/
SDA=dat>>7; // 數據右移7位 低位直接移走,高位移至SDA 起始信號之后SCL=0,所以可以直接改變SDA信號
dat=dat<<1; // 數據左移1位 移走最高位,次高位變為最高位 等待下一次循環 次高位賦值給SDA
Delay10us(); // 延遲10us
SCL=1; // 翻轉SCL
Delay10us(); //建立時間>4.7us
SCL=0; // SCL低電平,數據進行傳送 時間大于4us
Delay10us();
}
// 循環8次后,釋放SDA,SCL
SDA = 1;
Delay10us();
SCL = 1;
// 等待從機的應答 如果從機產生應答SDA變為低電平 發送失敗SDA變為高電平
while(SDA) // 判斷SDA(數據線)的狀態 如果SDA=0時,不成立,跳出循環
{
//限定的條件 沒有產生應答 始終為高電平
b++;
if(b>200) // 如果b > 200us 超過這個時間則認為它沒有產生應答
{
SCL=0;
Delay10us();
return 0; // 返回0 認為它沒有產生應答(發送數據不成功)
}
}
SCL=0;
Delay10us();
return 1; // 發送成功1 發送失敗0
}
// 字節接收函數 讀函數 先讀取高位,再讀取低位
unsigned char I2cReadByte()
{
unsigned char a=0,dat=0;
SDA=1;
Delay10us();
for(a=0;a<8;a++) // 讀取的數據有8位
{
SCL=1; // 高電平 穩定
Delay10us(); // 延遲10us
dat<<=1; // dat = dat << 1;dat的數據左移一個bit,右邊補0
dat |=SDA; // dat = dat|SDA dat與SDA只要有一個為1就為高電平
Delay10us();
SCL=0; // scl為0可以改變數據
Delay10us();
}
return dat;
}
// 具體的寫函數 通信AT24C02
void At24c02Write(unsigned char addr,unsigned char dat)
{
I2cStart(); // 起始信號
I2cSendByte(0xa0); //器件地址+0寫入 器件地址高四位格式固定
I2cSendByte(addr); // 首地址 發送要寫入內存地址
I2cSendByte(dat); // 發送數據
I2cstop();
}
// 讀取At24c02中一個數據
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2cStart();
I2cSendByte(0xa0); // 發送寫器件地址 0xa0的二進制10100000
I2cSendByte(addr); //發送要讀取的地址
I2cStart();
I2cSendByte(0xa1); // 0xa0的二進制10100001 器件地址 +1讀 器件地址高四位格式固定
num = I2cReadByte(); //讀取數據
I2cstop();
return num;
上一篇:DS18B20溫度傳感器 ------ 自學筆記
下一篇:51單片機之串口通信 ---- 自學筆記
推薦閱讀
史海拾趣