- //****************************************************************
- /*该程序的功能:利用定时器产生一个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;
- }
- }
-
复制代码
|