/******根据时间长短显示位数,显示1小时** ************带有小数点标识符************* **********首次上电会乱码***************** **********注释2009-06-16 17:42**********/ #include<reg52.h> #define uchar unsigned char #define uint unsigned int #define ulong unsigned long sbit sda=P3^3; // 定义sda sbit scl=P3^2; // 定义scl sbit dula=P2^4; // 数码管段选 sbit wela=P2^3; // 数码管位选 uchar num,sec,min,hour;// num为250ms的次数,sec为秒, min为分钟, hour为小时 uint ms;//毫秒数值大于256 uint secsum;// 总秒数 uchar code table[]={ 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e,0xff}; //0到F编码,共阳,0xff数码管不显示任何数 uchar code tabledot[]={ 0x40,0x79,0x24,0x30, 0x19,0x12,0x02,0x78,0x00, 0x10,0xff}; //0到9带小数点,0xff数码管不显示任何数 void delay()//延时大概几个机器周期 { ;; } void delay1ms(uint z)//延时毫秒级 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void start() //开始信号 { sda=1; delay(); scl=1; delay(); sda=0; delay(); } void stop() //停止 { sda=0; delay(); scl=1; delay(); sda=1; delay(); } void respons() //应答 { uchar i; scl=1; delay(); while((sda==1)&&(i<255))i++; scl=0; delay(); } void init()//I2C初始化 { 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(); 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; } void display(uchar mins,uchar ming,uchar secs,uchar secg)//数码管显示时间 { wela=1;//开数码管位选 P0=0x08; //送位选 delay1ms(5); wela=0; //锁存 dula=1; P1=table[mins]; //送段码 delay1ms(5); dula=0; //锁存
wela=1; P0=0x04; delay1ms(5); wela=0; dula=1; P1=tabledot[ming]; //送带小数点段码 delay1ms(5); dula=0; //锁存
wela=1;//开数码管位选 P0=0x02; //送位选 delay1ms(5); wela=0; //锁存 dula=1; P1=table[secs]; //送段码 delay1ms(5); dula=0; //锁存 wela=1;//开数码管位选 P0=0x01; //送位选 delay1ms(5); wela=0; //锁存 dula=1; P1=table[secs]; //送段码 delay1ms(5); dula=0; //锁存 } void main() { init();//I2C初始化 min=read_add(130); //读分钟数据 if(min>60) min=0; sec=read_add(131);//读秒数据 if(sec>60) sec=0; TMOD=0x02;//定时器0方式2 TH0=6; //赋初值,自动重装 TL0=6; TCON=0x10; //开TR0 IE=0x82; //开EA,ET0 delay1ms(1000); while(1) { secsum=sec+min*60;//计算总时间,单位是秒 if(secsum<10) //几秒,只显示最后一位 display(16,10,16,sec); else { if(secsum<60)//几十秒,只显示最后两位 display(16,10,sec/10,sec%10); else { if(secsum<600)//几分钟,只显示最后三位 display(16,min,sec/10,sec%10); else { //if(secsum<3600)//十几分钟,前两位不显示 display(min/10,min%10,sec/10,sec%10);
} } }
} } void time0() interrupt 1 { num++;//自动重装 if(num==4)//1ms { num=0; ms++; if(ms==1000)//1s { ms=0; sec++;
if(sec==60)//1分钟 { sec=0; min++; if(min==60)//1小时 { min=0; } write_add(130,min);//在地址130写分钟数据 } write_add(131,sec);//在地址131写秒表地址 }
} }
[此贴子已经被作者于2009-6-22 21:21:03编辑过] |