AT24C02是由ATMEL公司提供的,IIC總線串行EEPROM(electronic eraser programmer read only memory),其容量為2kbit(256B),工作電壓在2.7v"5.5v之間,生產工藝是CMOS。 一般數字芯片都在左下角和右上角為GND,VCC。容量的計算方法:AT24Cxx :01"1024 容量 = xx * 1kbit。 寫入過程: AT24C系列EEPROM芯片的固定部分為1010,A2,A1,A0引腳接高低電平后得到確定的3位編碼,形成7位編碼即為該器件的地址碼。 單片機進行寫操作時,首先發送該器件的7位地址碼和寫方向位”0”(共8位,即一個字節),發送完后釋放SDA線并在SCL線上產生第9個時鐘信號。被選中的存儲器器件在確認是自己的地址后,在SDA線上產生一個應答信號作為響應,單片機收到應答后就可以傳送數據了。傳送數據時,單片機首先發送一個字節的被寫入存儲器的首地址,收到存儲器器件的應答后,單片機就逐個發送數據字節,但每發送一個字節后都要等待應答。AT24C系列片內地址在接收到每一個數據字節地址后自動加1,在芯片的“一次裝載字節數”限度內,只需輸入首地址。裝載字節數超過芯片的“一次裝載字節數”時,數據地址將“上卷”,前面的數據將被覆蓋。 字節寫: 頁寫: 讀入過程: 單片機先發送該器件的7位地址碼和寫方向位“0”(“偽寫”),發送完后釋放SDA線并在SCL線上產生第9個時鐘信號。被選中的存儲器器件在確認是自己的地址后,在SDA線上產生一個應答信號作為回應。 然后,再發一個字節的要讀出器件的存儲區的首地址,收到應答后,單片機要重復一次起始信號并發出器件地址和讀方向位(“1”),收到器件應答后就可以讀出數據字節,每讀出一個字節,單片機都要回復應答信號。當最后一個字節數據讀完后,單片機應返回以“非應答”(高電平),并發出終止信號以結束讀出操作。 當前地址讀: 隨機讀: 有序讀: IIC總線模擬時序圖: IIC總線應答時序圖: 設備地址: 寫周期: 兩次寫之間要有一個10ms的twR間隔 寫入EEPROM一個2,然后讀出,在數碼管上顯示出來: #include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit SCL = P3^6; sbit SDA = P3^7; void delay() { ;; } //5us void delay1(uchar x) { uchar a,b; for(a=x;a>0;a--) for(b=100;b>0;b--); } void Init(){ SCL = 1; SDA = 1; } void start(){ SDA = 1; delay(); SCL = 1; delay(); SDA = 0; delay(); } void stop(){ SDA = 0; delay(); SCL = 1; delay(); SDA = 1; delay(); } void write(uchar date) { uchar i,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; SCL=0; delay(); SDA=CY; delay(); SCL=1; delay(); } SCL=0; delay(); SDA=1; delay(); } uchar read() { uchar i,k; SCL=0; delay(); SDA=1; delay(); for(i=0;i<8;i++) { SCL=1; delay(); k=(k<<1)|SDA; // 將SDA賦給K的每一位 SCL=0; delay(); } return k; } void response(){ int i; SCL = 1; //在SCL為高電平期間,進行應答 delay(); while((SDA == 1) && (i < 170))i++; //SCL釋放總線,等待從設備應答,從設備會把SDA拉低 SCL = 0; delay(); } void At24c_Write(uchar address, uchar value){ start(); write(0xa0); //寫入設備地址 response(); write(address); //寫入首地址 response(); write(value); //寫入數據 response(); stop(); } uchar At24c_Read(uchar address){ uchar value; start(); write(0xa0); //偽寫,先寫入設備地址 response(); write(address); //再寫入要讀取數據的首地址 response(); start(); //再次 write(0xa1); //寫入要讀取數據的地址,方向為1 response(); value = read(); //讀取數據 stop(); return value; } void main(){ P1 = 0x0; // 位選,使最地位數碼管被選中 Init(); At24c_Write(23,0x5b); // 在EEPROM的23這個地址上寫數據0x5b delay1(100); // 在寫和讀之間要多延時一會兒,否則器件處理不完 P2 = At24c_Read(23); // 讀取23地址的數據,也就是剛才寫入的數據 while(1); } 掉電后數據不丟失,復位后,仍然從剛才掉電的數字開始往下顯示。從0"9 #include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit SCL = P3^6; sbit SDA = P3^7; uchar temp, sum; uint flag; unsigned char code duan[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, 0x77,0x7C,0x39,0x5E,0x79,0x71}; void delay() { ;; } //5us void delay1(uchar x) { uchar a,b; for(a=x;a>0;a--) for(b=100;b>0;b--); } void Init(){ SCL = 1; SDA = 1; } void start(){ SDA = 1; delay(); SCL = 1; delay(); SDA = 0; delay(); } void stop(){ SDA = 0; delay(); SCL = 1; delay(); SDA = 1; delay(); } void write(uchar date) { uchar i,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; SCL=0; delay(); SDA=CY; delay(); SCL=1; delay(); } SCL=0; delay(); SDA=1; delay(); } uchar read() { uchar i,k; SCL=0; delay(); SDA=1; delay(); for(i=0;i<8;i++) { SCL=1; delay(); k=(k<<1)|SDA; // 將SDA賦給K的每一位 SCL=0; delay(); } return k; } void response(){ int i; SCL = 1; //在SCL為高電平期間,進行應答 delay(); while((SDA == 1) && (i < 170))i++; //SCL釋放總線,等待從設備應答,從設備會把SDA拉低 SCL = 0; delay(); } void At24c_Write(uchar address, uchar value){ start(); write(0xa0); //寫入設備地址 response(); write(address); //寫入首地址 response(); write(value); //寫入數據 response(); stop(); } uchar At24c_Read(uchar address){ uchar value; start(); write(0xa0); //偽寫,先寫入設備地址 response(); write(address); //再寫入要讀取數據的首地址 response(); start(); //再次 write(0xa1); //寫入要讀取數據的地址,方向為1 response(); value = read(); //讀取數據 stop(); return value; } void main(){ uint i; flag = 1; P1 = 0x0; // 位選,使最地位數碼管被選中 EA = 1; ET0 = 1; sum = 0; temp = 0; TMOD = 0x01; TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; TR0 = 1; Init(); P2 = At24c_Read(23); for(i = 0; i < 10; i++) if(duan[ i] == P2){ sum = i; break; flag = 0; } while(1){ if(temp == 20){ temp = 0; if(sum == 10){ sum = 0; } if(flag == 1){ At24c_Write(23,duan[sum]); delay1(100); P2 = duan[sum]; } sum++; } } } void time0() interrupt 1{ TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; temp++; } |