设计数字电子时钟电路: 功能要求:
(1) 用 6 位数码管显示,显示格式:时.分.秒,开机缺省时间显示
11.59.58。
(2) 12/24 小时制切换(按键切换)。
(3) 可校准:按键设置时钟(时分秒)初始值。
(4) 秒表功能:按键启动、停止,最大计时 999.9 秒(4 位数码管显示)。
(5)秒表功能模式时时钟正常运行,不受影响。
该程序前四条都满足,第五条不满足
我尝试修改了一下,编译通过,但在proteus上仿真结果不满足要求。图如下:
原程序在Proteus仿真后的结果:
我的程序对应的结果:
待修改程序和我修改的部分程序如下:
待修改程序:
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit led1=P3^0;
sbit led2=P3^1;
//数码管编码,该部分我改成了如下:
//sbit P2_0=P2^0;
//sbit P2_1=P2^1;
//sbit P2_2=P2^2;
//sbit led1=P2^3;
//sbit led2=P2^4;
//sbit P2_5=P2^5;
//sbit P2_6=P2^6;
//sbit P2_7=P2^7;
uchar code smgduan0[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9,无小数点
uchar code smgduan1[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//显示0~9,有小数点
uchar mode=0;//模式.正常,设置,秒表
uchar flag=0;
uchar time=0,miao=58,fen=59,shi=11,pm=0;
uint sec=0,start=0;//秒表控制
uchar key_scan()//按键检测
{
uchar i,j;
i=0;
j=0;
P1=0x0f;
if(P1!=0x0f) //检测有无按下
{
switch(P1)//检测行
{
case 0x0e:i=1;break;
case 0x0d:i=5;break;
case 0x0b:i=9;break;
case 0x07:i=13;
}
P1=0xf0;
switch(P1)//检测列
{
case 0xe0:j=0;break;
case 0xd0:j=1;break;
case 0xb0:j=2;break;
case 0x70:j=3;
}
while(P1!=0xf0);//等待按键松开
}
return i+j;
}
//延时
void delay(uint i)
{
while(i--);
}
//主函数
void main()
{
uchar key=0,i;
TMOD|=0X01;
TH0=0X3C;
TL0=0XB0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
while(1)
{
key=key_scan();//按键检测
switch(key)
{
case 1://设置
if(mode==0)
mode=1;
else
mode=0;
break;
case 2://时加
if((mode==1)&&(shi<23))
{
shi++;
}
break;
case 3://分加
if((mode==1)&&(fen<59))
{
fen++;
}
break;
case 4://秒加
if((mode==1)&&(miao<59))
{
miao++;
}
break;
case 5://切换12/24
pm=!pm;
break;
case 6://时减
if((mode==1)&&(shi>0))
{
shi--;
}
break;
case 7://分减
if((mode==1)&&(fen>0))
{
fen--;
}
break;
case 8://秒减
if((mode==1)&&(miao>0))
{
miao--;
}
break;
case 9://秒表
mode=2;
break;
case 10://开始
start=1;
break;
case 11://停止
start=0;
break;
case 12://复位
start=0;
sec=0;
}
//显示
if(shi>11)
led2=0;
else
led2=1;
if(mode==0) //时间显示
{
if(pm==0)//24
{
led1=1;
P0=0;P2=0;P0=smgduan0[shi/10];delay(100);
P0=0;P2=1;P0=smgduan1[shi%10];delay(100);
P0=0;P2=2;P0=smgduan0[fen/10];delay(100);
P0=0;P2=3;P0=smgduan1[fen%10];delay(100);
P0=0;P2=4;P0=smgduan0[miao/10];delay(100);
P0=0;P2=5;P0=smgduan0[miao%10];delay(100);
//此处改成如下,即将P2变成位的格式,下同,就省略不写了:
//led1=1;
// P0=0;P2_0=0;P2_1=0;P2_2=0;P0=smgduan0[shi/10];delay(100);
//P0=0;P2_0=0;P2_1=0;P2_2=1;P0=smgduan1[shi%10];delay(100);
// P0=0;P2_0=0;P2_1=1;P2_2=0;P0=smgduan0[fen/10];delay(100);
//P0=0;P2_0=0;P2_1=1;P2_2=1;P0=smgduan1[fen%10];delay(100);
//P0=0;P2_0=1;P2_1=0;P2_2=0;P0=smgduan0[miao/10];delay(100);
//P0=0;P2_0=1;P2_1=0;P2_2=1;P0=smgduan0[miao%10];delay(100);
}
else //12
{
led1=0;
if(shi>11)
i=shi-12;
else
i=shi;
P0=0;P2=0;P0=smgduan0[i/10];delay(100);
P0=0;P2=1;P0=smgduan1[i%10];delay(100);
P0=0;P2=2;P0=smgduan0[fen/10];delay(100);
P0=0;P2=3;P0=smgduan1[fen%10];delay(100);
P0=0;P2=4;P0=smgduan0[miao/10];delay(100);
P0=0;P2=5;P0=smgduan0[miao%10];delay(100);
//此处改成如下,即将P2变成位的格式,下同:
// P0=0;P2_0=0;P2_1=0;P2_2=0;P0=smgduan0[i/10];delay(100);
// P0=0;P2_0=0;P2_1=0;P2_2=1;P0=smgduan1[i%10];delay(100);
//P0=0;P2_0=0;P2_1=1;P2_2=0;P0=smgduan0[fen/10];delay(100);
//P0=0;P2_0=0;P2_1=1;P2_2=1;P0=smgduan1[fen%10];delay(100);
//P0=0;P2_0=1;P2_1=0;P2_2=0;P0=smgduan0[miao/10];delay(100);
//P0=0;P2_0=1;P2_1=0;P2_2=1;P0=smgduan0[miao%10];delay(100);
}
}
if(mode==1)//设置
{
if(time<11)
{
P0=0;P2=0;P0=smgduan0[shi/10];delay(100);
P0=0;P2=1;P0=smgduan1[shi%10];delay(100);
P0=0;P2=2;P0=smgduan0[fen/10];delay(100);
P0=0;P2=3;P0=smgduan1[fen%10];delay(100);
P0=0;P2=4;P0=smgduan0[miao/10];delay(100);
P0=0;P2=5;P0=smgduan0[miao%10];delay(100);
}
else
{
P0=0;P2=0;P0=smgduan0[shi/10];delay(100);
P0=0;P2=1;P0=smgduan0[shi%10];delay(100);
P0=0;P2=2;P0=smgduan0[fen/10];delay(100);
P0=0;P2=3;P0=smgduan0[fen%10];delay(100);
P0=0;P2=4;P0=smgduan0[miao/10];delay(100);
P0=0;P2=5;P0=smgduan0[miao%10];delay(100);
}
}
if(mode==2)//秒表
{
P0=0;P2=2;P0=smgduan0[(sec/2)/1000];delay(100);
P0=0;P2=3;P0=smgduan0[(sec/2)%1000/100];delay(100);
P0=0;P2=4;P0=smgduan1[(sec/2)%100/10];delay(100);
P0=0;P2=5;P0=smgduan0[(sec/2)%10];delay(100);
}
}
}
//定时器中断
void Timer0() interrupt 1
{
if(mode==0)//正常
{
if(time<20)
time++;
else
{
time=0;
if(miao<59)
miao++;
else
{
miao=0;
if(fen<59)
fen++;
else
{
fen=0;
if(shi<23)
shi++;
else
shi=0;
}
}
}
}
if(mode==1)//设置
{
if(time<20)
time++;
else
time=0;
}
if(mode==2)//秒表
{
if(start==1)
{
sec++;
}
}
TH0=0X3C;//50ms
TL0=0XB0;
}