給別人做的個(gè)東西,要求數(shù)據(jù)掉電保存,大的框架很早就搭建起來了,但是到了24C02這,卡住了。不是無法實(shí)現(xiàn)存儲(chǔ),只是我的數(shù)據(jù)量比較大,好幾天在網(wǎng)上搜索24C02相關(guān)的程序,幾乎把所有的能看的都看遍了,我失望的才發(fā)現(xiàn),大同小異,大家都是互相抄來抄去的,沒有一個(gè)能很好用的,而且有的程序又是缺個(gè)括號(hào),或者只有括號(hào)的一半,另一半和里邊的變量都不知道跑哪去了,看的很是郁悶啊,開始想,不到萬不得已,堅(jiān)決不看英文的技術(shù)手冊,今早一大早泡圖書館看書查資料,復(fù)印了好幾十頁,到了實(shí)驗(yàn)室又打印了技術(shù)文檔,邊看邊查單詞邊翻譯,還有在我的好兄弟的一起協(xié)助下,終于輕松實(shí)現(xiàn)了24C02存儲(chǔ)255個(gè)數(shù)據(jù)。同時(shí)也大體明白了24C02得工作原理。
1、24C02是2Kbits 意思是有2048bit,換算成字節(jié)是256Byte,也就是說最多可以存儲(chǔ)255個(gè)字節(jié)的數(shù)據(jù);
2、ATMEl24C02(應(yīng)該其他廠家的24C02也是這樣子吧。。。)有32頁,每頁可以存放8個(gè)字節(jié);
3、24C02有兩種工作模式:(1)、字節(jié)寫入模式:結(jié)合技術(shù)文檔我認(rèn)為該模式是這樣工作的:首先是可以再任意的地址(0x00~0xFF)寫入一個(gè)字節(jié),也可以在某一地址連續(xù)的寫入N字節(jié),而且不需要翻頁,從技術(shù)手冊得知,答題時(shí)說字節(jié)寫入模式下,頁指針根寫入數(shù)據(jù)的多少來自動(dòng)增加實(shí)現(xiàn)翻頁功能,不用自己在程序里邊實(shí)現(xiàn);
(2)、頁寫入模式:頁寫入模式下,手冊上寫著,一頁可以存8字節(jié),當(dāng)存儲(chǔ)的數(shù)據(jù)大于8時(shí),則會(huì)覆蓋先前保存的數(shù)據(jù),例如,有16個(gè)數(shù)據(jù) uchar data[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},從24C02的0x00地址開始存放,當(dāng)存完一頁(8個(gè))時(shí),第9個(gè)數(shù)據(jù)會(huì)保存在0x00,覆蓋掉開始保存的1,后邊的數(shù)據(jù)一次類推,這樣的現(xiàn)象叫做“翻轉(zhuǎn)”,如果想寫完一頁后將剩余的數(shù)據(jù)保存在下一頁,頁指針需要自己來設(shè)定。
我覺著,字節(jié)寫入模式相對更簡單些。
下邊,附上我的程序,供大家參考,如有疑問的地方,歡迎大家交流!
///使用單片機(jī):89S51
///晶振:12MHz
#include<reg52.h>
#include "INTRINS.H"
#define uchar unsigned char
#define uint unsigned int
sbit scl = P3^2;
sbit sda = P3^3;
/*********74H573控制端*********/
sbit dula = P2^7;//段選
sbit wela = P2^6;//位選
sbit LED = P2^5;//秒顯示
uchar tt=0;
uchar i=0,j=0,temp=0,a=0,b=0,c=0;
/*******數(shù)碼管段選_時(shí)間********/
uchar code table_duan[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
/*********數(shù)碼管位選**********/
uchar code table_wei[]={0xfe,0xfd,0xfb,0xf7,0xef};
void delay1(uint x)
{
uint i,j ;
for(i=x;i--;i>0)
for(j=110;j--;j>0);
}
/**************************** 顯示函數(shù) **************************/
void display(uchar wee,uchar H_hour,uchar L_hour,uchar H_min,uchar L_min)
{
dula=1;
P0=table_duan[wee];//數(shù)碼管5位,星期
dula=0;
wela=1;
P0=table_wei[0];
wela=0;
delay1(1);
dula=1;
P0=table_duan[H_hour];//數(shù)碼管4位,小時(shí)十位
dula=0;
wela=1;
P0=table_wei[1];
wela=0;
delay1(1);
dula=1;
P0=table_duan[L_hour];//數(shù)碼管3位,小時(shí)個(gè)位
dula=0;
wela=1;
P0=table_wei[2];
wela=0;
delay1(1);
dula=1;
P0=table_duan[H_min];//數(shù)碼管2位,分鐘十位
dula=0;
wela=1;
P0=table_wei[3];
wela=0;
delay1(1);
dula=1;
P0=table_duan[L_min];//數(shù)碼管1位,分鐘個(gè)位
dula=0;
wela=1;
P0=table_wei[4];
wela=0;
delay1(1);
}
void delay()
{ ;; }
void start() //開始信號(hào)
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop() //停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons() //應(yīng)答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
void init()
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(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();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void write_add(uchar address,uchar date)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_add(uchar address)
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
/*-------------------------------------------------------------
主程序
功能:實(shí)現(xiàn)存儲(chǔ)器EEPROM AT24C02的數(shù)據(jù)讀寫操作
------------------------------------------------------------*/
void main()
{
TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;//開總中斷
ET0=1;//開定時(shí)器0中斷
TR0=0;//啟動(dòng)定時(shí)器0
P2=P2&0xc0;
init();
for(i=0; i<255; i++)
{
write_add(i,i);
delay1(1);
}
TR0=1;
while(1)
{
if(j == 255)j=0;
TR0=0;
temp=read_add(j);
TR0=1;
a=temp/100;
b=temp%100/10;
c=temp%100%10;
display(a,b,c,0,0);
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if(tt == 5)
{
tt = 0;
LED = ~LED;//用于指示是否工作正常
j++;
}
}
|