请高手用单片机C语言编写c51时钟程序,含有6个数显管,3个按键,要自己写的,不要百度什么的复制粘贴

如题所述

这是我初学时写的,刚好也是数码管 /*位选接P2口,三个按钮分别接P25~P27。段码接P1,T0计数
*/
#include<reg51.h>
#define DOU 1818//按键消抖时间sbit led_1=P2^0;
sbit led_2=P2^1;
sbit led_3=P2^2;
sbit led_4=P2^3;
sbit led_5=P2^4;
sbit dp=P1^7;sbit an_mod=P2^5;
sbit an_movright=P2^6;
sbit an_up=P2^7;unsigned char code tab[]={0x90,0xd7,0xa2,0x86,0xc5,0x8c,0x88,0xd6,0x80,0x84};unsigned char num=0,hour=0,minute=0,secon=0,week=1;//20个num是一秒
unsigned char hour_1=0,hour_2=0,minute_1=0,minute_2=0,week_1=1;
bit first_flag=0,adj=0;
unsigned char mod=0;
unsigned char led_mov=0;/*以上是全局变量*/void init()
{
P1=0XFF;
P2=0xff;
EA=1;//开放中断
ET0=1;
PT0=1;//设T0优级
TMOD=0X01;//T0以16位计时方式工作
TH0=0x3c;//49996us
TL0=0xb7;
TR0=1;
}void delay(unsigned int us)
{
while(--us);
}void led_show()
{
if((hour/10)<=0)//时第一位小于10,则关闭第一位显示
{
led_1=1;
}else
{
P1=tab[hour/10];
led_1=0;//开1
delay(250);
led_1=1;
} P1=tab[hour%10];
if(num<10){dp=1;}//秒点熄灭
else{dp=0;}//秒点点亮
led_2=0;//开2
delay(230);
led_2=1;
P1=tab[minute/10];
led_3=0;//开3
delay(290);
led_3=1;
P1=tab[minute%10];
led_4=0;//开4
delay(290);
led_4=1;
P1=tab[week];
led_5=0;//开5
delay(80);
led_5=1;
}void led_adj()
{
P1=tab[hour_1];
led_1=0;//开1
if(led_mov==0){delay(200);}else{
delay(2);}
led_1=1; P1=tab[hour_2];
led_2=0;//开2
if(led_mov==1){delay(200);}else{
delay(2);}
led_2=1; P1=tab[minute_1];
led_3=0;//开3
if(led_mov==2){delay(200);}else{
delay(2);}
led_3=1; P1=tab[minute_2];
led_4=0;//开4
if(led_mov==3){delay(200);}else{
delay(2);}
led_4=1; P1=tab[week_1];
led_5=0;//开5
if(led_mov==4){delay(50);}else{
delay(1);}
led_5=1;
}void keyscan()
{
switch(mod)
{
case 0:
if(an_mod==0)
{
delay(DOU);
if(an_mod==0){
mod=1;
}
while(!an_mod);
}
if(an_up==0)
{
delay(DOU);
if(an_up==0){
mod=2;
}
while(!an_up);
}
break;
case 1:
if(first_flag==0)//first_flag=0代表第一次扫描,把当前时间赋值给调整时间
{
led_mov=0;
hour_1=hour/10;
hour_2=hour%10;
minute_1=minute/10;
minute_2=minute%10;
week_1=week;
first_flag=1;//将first_flag置位
}else{
if(an_mod==0&&adj==0)//按模式键 adj=0代表没有调整过数值,将不改变任何设置直接退出
{
delay(DOU);
if(an_mod==0){
mod=0;
first_flag=0;
}
while(!an_mod);
}
if(an_movright==0)//右移键
{
delay(DOU);
if(an_movright==0){
led_mov++;
}
while(!an_movright);
}
if(an_up==0)//向上调整时间
{
delay(DOU);
if(an_up==0)
{
switch(led_mov)
{
case 0:hour_1++;
break;
case 1:hour_2++;
break;
case 2:minute_1++;
break;
case 3:minute_2++;
break;
case 4:week_1++;
break;
}
adj=1;
}
while(!an_up);
}
if(an_mod==0&&adj==1)//经过调整后按mod键写入数据
{
delay(DOU);
if(an_mod==0)
{
first_flag=0;//确定后重新置位
adj=0;
mod=0;
hour=hour_1*10+hour_2;
minute=minute_1*10+minute_2;
secon=0;
week=week_1;
num=0;
}
while(!an_mod);
}
}
break;
case 2:
if(an_up==0)
{
delay(DOU);
if(an_up==0){mod=0;}
while(!an_up);
}
}
}void check_num()
{
if(week>=8){week=1;} if((hour_1*10+hour_2)>=24){hour_1=0;hour_2=0;}
if(minute_1>=7){minute_1=0;}
if(minute_2>=10){minute_2=0;}
if(week_1>=8){week_1=1;} if(led_mov>=5){led_mov=0;}
}void conver()
{
if(num>=20)
{
secon++;
num=0;
if(secon>=60){minute++;secon=0;}
if(minute>=60){hour++;minute=0;}
if(hour>=24){week++;hour=0;}
// if(hour==23&&minute==55&&secon==0){secon=secon+1;}//每天的23时55分0秒自动校准时间
}
}
void main()
{
init();
while(1)
{
keyscan();
switch(mod)
{
case 0:led_show();
break;
case 1:led_adj();
break;
case 2:P1=0xff;P2=0xff;
}
conver();
check_num();
}
}void zd() interrupt 1
{
TH0=0x3c;//49996us
TL0=0xb7;

num++;
}
温馨提示:答案为网友推荐,仅供参考
相似回答
大家正在搜