/******根据时间长短显示位数,显示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 = 0,sec = 0,min = 0,hour = 0;// num为250ms的次数,sec为秒, min为分钟, hour为小时 uint ms;//毫秒数值大于256 uchar sec_temp,min_temp; 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; dula=1; P0=0x08; //送位选 P1=table[mins]; //送段码 dula=0; //锁存 wela=0; delay1ms(5); wela=1; dula=1; P0=0x04; P1=tabledot[ming]; //送带小数点段码 dula=0; //锁存 wela=0; delay1ms(5); wela=1; dula=1; P0=0x02; //送位选 P1=table[secs]; //送段码 dula=0; //锁存 wela=0; delay1ms(5); wela=1; dula=1; P0=0x01; //送位选 P1=table[secg]; //送段码 *******此处修改为secg dula=0; //锁存 wela=0; delay1ms(5); } void main() { init();//I2C初始化 TMOD=0x02;//定时器0方式2 TH0=6; //赋初值,自动重装 TL0=6; TCON=0x10; //开TR0 IE=0x82; //开EA,ET0 min=read_add(130); //读分钟数据 sec=read_add(131);//读秒数据 if(min >= 60) { min = 0; } if(sec >= 60) { sec = 0; } 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) { sec = 0; min++; } write_add(131,sec);//在地址131写秒表地址 write_add(130,min);//在地址130写分钟数据 if(min >= 60)//1小时 { min=0; } } } } 修改后的程序 如上所示,请参考一下 |