|
單片機(jī)源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define AT24C02_addr
- bit write=0;//寫24C02的標(biāo)志
- sbit sda=P2^0;
- sbit scl=P2^1;
- sbit dula=P2^6;//申明U1鎖存器的鎖存端
- sbit wela=P2^7;//U2鎖存端
- uchar i,miao,t;
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- void Delay5us() //@11.0592MHz
- {
- uchar i;
- _nop_();
- i = 11;
- while (--i);
- }
- void start()//起始信號(hào)
- {
- scl=1;//先保持高電平,再進(jìn)行數(shù)據(jù)傳輸
- _nop_();//延時(shí)1微秒
- sda=1;
- Delay5us();//函數(shù)調(diào)用
- sda=0;
- Delay5us();
- }
- void stop()
- {
- scl=1;
- _nop_();
- sda=0;
- Delay5us();
- sda=1;
- Delay5us();
- }
- void Mster_ASK()//主機(jī)發(fā)送應(yīng)答
- {
- uchar i;
- scl=1;
- _nop_();
- if(i==1)//受控器做出響應(yīng)
- {
- sda=0;//釋放sda線送出應(yīng)答信號(hào)
- }
- else
- {
- sda=1;
- }
- _nop_();
- scl=1;//數(shù)據(jù)保持穩(wěn)定
- Delay5us();
- scl=0;//占用總線進(jìn)行通信
- sda=1;//準(zhǔn)備下一次的通信
- }
- void test_ASK()//從機(jī)接受應(yīng)答,低電平為應(yīng)答
- {
- scl=1;//scl為高電平,數(shù)據(jù)不允許改變
- Delay5us();
- if(sda==1)//因?yàn)閟da等于1時(shí),表示空閑狀態(tài)
- {
- scl=0;//表示不應(yīng)答
- _nop_();
- stop();
- return (0);
- }
- else//sda等于0,表示應(yīng)答,scl拉低,表示收到這個(gè)是否應(yīng)達(dá)的信息
- {
- scl=0;//低電平有效
- _nop_();
- return (1);
- }
- }
- uchar sendbyte(uchar byte)//傳送(寫)一個(gè)字節(jié)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- scl=0;//低電平時(shí)數(shù)據(jù)可以改變
- _nop_();//穩(wěn)定一下
- if(byte&0x80)
- {
- sda=1;//發(fā)一個(gè)1的數(shù)據(jù),先發(fā)高位
- _nop_();
- }
- else
- {
- sda=0;//如果if處是0的話,就說明最高位是0,所以傳數(shù)據(jù)0
- _nop_();
- }
- scl=1;//數(shù)據(jù)手冊(cè)看出來
- _nop_();
- byte<<=1;
- }
- }
- uchar readbyte()//讀一個(gè)字節(jié)
- {
- uchar dat,i;
- scl=0;//可要可不要吧,看它忙不忙
- _nop_();
- scl=1;//置1,數(shù)據(jù)不允許改變
- _nop_();
- for(i=0;i<8;i++)
- {
- scl=1;//置1,數(shù)據(jù)不允許改變
- _nop_();
-
- if(sda)//若為1,則要讀1出來
- {
- dat=dat|0x01;//或上都等于1
- else
- {
- dat=dat&0xfe;//與上都等于0
- }
- _nop_();
- scl=0; //釋放總線,允許下一次數(shù)據(jù)輸入
- dat<<=1;
- }
- }
- }
- void T0()interrpt 1//定時(shí)中斷服務(wù)函數(shù)
- {
- uchar t,miao,write;
- TH0=(65536-50000)/256//從15536開始裝初值,裝滿5000,即為50ms
- TL0=(65536-50000)%256//裝計(jì)數(shù)初值
- t++;
- if(t==20)//表示記滿1秒
- {
- t=0;//重新計(jì)數(shù)
- miao++;
- }
- if(miao=100)
- miao=0;//重新計(jì)數(shù)
- }
- void display()
- {
- uchar bai,ge;
- wela=1;//打開位選
- P0=0x7e;//點(diǎn)亮第一位數(shù)碼管
- wela=0;//關(guān)閉位選
- dula=1;;//打開段選
- P0=table[bai];
- dula=0;
- wela=1;
- P0=0x7d;
- wela=0;
- dula=1;
- P0=table[ge];
- dula=0;
- main()
- {
- ACK_flag=0;
- Init();//初始化
- start();
- sendbyte(AT24C02+0)//器件地址加0
- if(!test_ASK())//若不應(yīng)答,則為假,然 后取反
- {
- ACK_flag=1;
- }
- t=readbyte();//讀出的時(shí)間賦予t
- if(t>100)
- t=0;//預(yù)防首次讀取出錯(cuò)誤數(shù)據(jù)
- TMOD=0x01;//定時(shí)器工作在方式1
- ET0=1;//開定時(shí)器0
- EA=1;//開總定時(shí)器
- TH0=(65536-50000)/256;//對(duì)TH0TL0賦值
- TL0=(65536-50000)%256;//使定時(shí)器50毫秒中斷一次
- TR0=1;//開始計(jì)時(shí)
- while(1)
- {
- display(t/10,t%10)
- if(write==1)//判斷計(jì)時(shí)器是否為1秒
- {
- write=0;//清0
- sendbyte(2,t)//在地址2中寫入數(shù)據(jù)t
- }
-
- }
- }
- void write_address(uchar date,uchar address)
- {
- start();
- writebyte(0xa0);
- Mster_ASK;//應(yīng)答
- write_byte(date);
- test_ASK;//應(yīng)答
- stop();
- }
- void read_add(uchar address)
- {
- uchar date;
- start();
- writebyte(0xa0);
- Mster_ASK();
- writebyte(address);
- test_ASK();
- start();
- writebyte(0xa1);
- Mster_ASK();
- test_ASK();
- date=writebyte();
- stop();
- return date;
- }
- bit I2C_WriteData(uchar ADDR,uchar DAT) //I2C寫數(shù)據(jù)
- {
- I2C_Start();
- I2C_send_byte(AT24C02_ADDR+0);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(ADDR);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(DAT);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_Stop();
- return(1);
- }
- uchar I2C_ReadData(uchar ADDR) //I2C讀數(shù)據(jù)
- {
- uchar dat;
- I2C_Start();
- I2C_send_byte(AT24C02_ADDR+0);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(ADDR);
- if (!Test_ACK())
- {
- return(0);
- }
- Master_ACK(0);
- I2C_Start();
- I2C_send_byte(AT24C02_ADDR+1);
- if (!Test_ACK())
- {
- return(0);
- }
- dat = I2C_read_byte();
- Master_ACK(0);
- I2C_Stop();
- return(dat);
- }
- void main()
- {
- I2C_init();
- Timer0_init();
- EEPROM_DATA = I2C_ReadData(255); //上電后首先讀出24C02第255單元的值
- while(1)
- {
- display(EEPROM_DATA);//數(shù)碼管顯示
-
- }
- }
- /*定時(shí)器0中斷服務(wù)程序*/
- void timer0() interrupt 1 //T0內(nèi)部查詢順序1
- {
- uchar i;
- TH0 = 0x4b;
- TL0 = 0xfe; //T0 定時(shí)50ms
- i++;
- if (i == 100) //5秒時(shí)間到
- {
- i = 0; //計(jì)數(shù)清零
- if (EEPROM_DATA < 99) //判斷待寫數(shù)據(jù)值
- {
- EEPROM_DATA++;
- }
- else
- {
- EEPROM_DATA = 0;
- }
- if(!I2C_WriteData(255,EEPROM_DATA)) //寫入待寫數(shù)據(jù)并判斷是否成功寫入
- {
- LED1 = 0;//如果寫失敗 讓LED1小燈點(diǎn)亮
- }
- else
- {
- LED1 = 1;
- }
- }
- }
復(fù)制代碼
|
|