- //****************************************************************
- /*該程序的功能:利用定時器產生一個0~99秒變化的秒表,并在數碼管上顯
- 示,每一秒中將該變化寫入AT24c02內部。當關閉電源,
- 且再次打開電源時單片機先從AT24c02中將原來寫入的數據
- 讀出來,接著顯示在數碼管上
- 應用到的知識:定時器中斷、艾方西(IIC)數據傳輸協議。
- 涉及芯片資料:AT24C02,74HC595
- */
- //****************************************************************
- #include<reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- uchar code num[]={0x80,0xed,0x42,0x48,0x2c,0x18,0x10,0xcc,0x00,0x08};//字段的顯示碼
- uint p=0,a,b;
- //*****AT24c02管腳的定義*********
- sbit scl=P0^3;
- sbit sda=P0^4;
- //*****595數碼管管腳定義*********
- sbit rck=P2^0;
- sbit sck=P2^1;
- sbit si=P2^2;
- //********函數的聲明**********
- void delayus();
- void start();
- void stop();
- void ack();
- void noack();
- void write_byte(uchar date);
- uchar read_byte();
- void xie(uchar add,uchar date);
- uchar du(uchar add);
- void init_24c02(); //24c02函數初始化
- void init_zhongduan(); //中斷函數初始化
- void write_595(uchar date);//595寫字節函數
-
- //*******************
- void delayus()
- {
- ; ; ;
- }
- /*void delayms(uint t)
- {
- uint i,j;
- for(i=t;i>0;i--)
- for(j=110;j>0;j--);
- } */
- void start()
- {
- sda=1;
- delayus();
- scl=1;
- delayus();
- sda=0;
- delayus();
- }
- void stop()
- {
- sda=0;
- delayus();
- scl=1;
- delayus();
- sda=1;
- delayus();
- }
- void ack()
- {
- uint i=0;
- scl=1;
- delayus();
- if((sda==1)&&(i<250))i++;
- scl=0;
- delayus();
- }
- void noack()
- {
- sda=1;
- delayus();
- scl=0;
- delayus();
- scl=1;
- delayus();
- scl=0;
- delayus();
- }
- void write_byte(uchar date)
- {
- uint i;
- scl=0;
- for(i=0;i<8;i++)
- {
- if(date&0x80)
- {
- sda=1;
- }
- else
- {
- sda=0;
- }
- scl=1;
- date=date<<1;
- delayus();
- scl=0;
- delayus();
- }
- sda=1;
- delayus();
- }
- uchar read_byte()
- {
- uint i;
- uchar k=0x00;
- sda=1;
- delayus();
- scl=0;
- delayus();
- for(i=0;i<8;i++)
- {
- scl=1;
- delayus();
- k=k<<1;
- if(sda)
- {
- k++;
- }
- scl=0;
- delayus();
-
- }
- return k;
- }
- void xie(uchar add,uchar date)
- {
- start();
- write_byte(0xa0);
- ack();
- write_byte(add);
- ack();
- write_byte(date);
- ack();
- stop();
- }
- uchar du(uchar add)
- {
- uchar k;
- start();
- write_byte(0xa0);
- ack();
- write_byte(add);
- ack();
-
- start();
- write_byte(0xa1);
- ack();
- k=read_byte();
- noack();
- stop();
- return k;
- }
- void init_24c02()
- {
- sda=1;
- scl=1;
- }
- void init_zhongduan()
- {
- EA=1;//開啟總中斷
- ET1=1;//開啟定時器1中斷
- TMOD=0X10;//設置定時器1為工作方式
- TH1=(65536-50000)/256;//裝初值12兆晶振定時50毫秒數位50000
- TL1=(65536-50000)%256;
- TR1=1; //啟動定時器1
- }
-
- void main()
- {
- init_zhongduan();
- a=du(2);//讀回斷電時的數據
- b=du(1);
- write_595(num[b]);//數碼管初始化為斷電前得數值
- write_595(num[a]);
- while(1);
- }
- void cut() interrupt 3
- {
- TH1=(65536-50000)/256; //重裝初值
- TL1=(65536-50000)%256;
- p++; //p每加一次就是50毫秒
- write_595(num[b]);
- write_595(num[a]);
- if(p==20) //判斷是否夠一秒
- {
- p=0;//重置0
- a++;
- if(a==10)
- {
- a=0;
- b++;
- if(b==10)b=0;
- xie(1,b);//選地址1儲存b的值
- }
- xie(2,a);//選地址2儲存a的值
- }
- rck=0;
- rck=1;
- }
- void write_595(uchar date)
- {
- uint i;
- for(i=0;i<8;i++)
- {
- sck=0;
- date=date>>1;//移位寄存
- si=CY;
- sck=1;
- }
- }
-
復制代碼
|