LED数码管设计的可调式电子时钟
#define uchar unsigned char
#define uint unsigned int
uchar temp1,temp2,temp3,aa,miaoshi,miaoge,fenshi,fenge,shishi,shige;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
void display(uchar shishi,uchar shige,uchar fenshi,uchar fenge,uchar miaoshi,uchar miaoge);
sbit S1=P1^0;
sbit S2=P1^1;
sbit S3=P1^2;
void delay(uint z);
void init();
void main()
{
init();
while(1)
{
if(S1==0)
{
temp3++;
while(S1==0);
}
if(S2==0)
{
temp2++;
while(S2==0);
}
if(S3==0)
{
temp1++;
while(S3==0);
}
if(aa==20)
{
aa=0;
temp1++;
if(temp1==60)
{
temp1=0;
temp2++;
}
if(temp2==60)
{
temp2=0;
temp3++;
}
if(temp3==24)
{
temp3=0;
}
miaoshi=temp1/10;
miaoge=temp1%10;
fenshi=temp2/10;
fenge=temp2%10;
shishi=temp3/10;
shige=temp3%10;
}
display(shishi,shige,fenshi,fenge,miaoshi,miaoge);
}
}
void delay(uint z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void display(uchar shishi,uchar shige,uchar fenshi,uchar fenge,uchar miaoshi,uchar miaoge)
{
P2=0xbf;
P0=table[miaoshi];
delay(5);
P2=0x7f;
P0=table[miaoge];
delay(5);
P2=0xf7;
P0=table[fenshi];
delay(5);
P2=0xef;
P0=table[fenge];
delay(5);
P2=0xfe;
P0=table[shishi];
delay(5);
P2=0xfd;
P0=table[shige];
delay(5);
P2=0xdf;
P0=0x40;
delay(5);
P2=0xfb;
P0=0x40;
delay(5);
}
void init()
{
temp1=0;
temp2=0;
temp3=0;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
程序如上,还有仿真图,现在按键按下去,所有数码管的都会闪一下再加一,S3仿真图里我去掉了,用不上。
有没有大神会的,帮忙看看
你的按键扫描程序有毛病,给你一个类似的时钟程序,关键是看怎么处理按键不影响显示的。
//K1键调整小时,K2键调整分钟
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int //宏定义
#define uchar unsigned char //宏定义
sbit K1 = P3^4; //小时+,
sbit K2 = P3^5; //分钟+,
sbit dula=P2^6; //段
sbit wela=P2^7; //位
uchar code table[]={ //数组
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar data dis_buf[8];
uchar data dis_index;
uchar hour,min,sec; //定义时、分、秒变量
uchar sec100; //定义10ms计时变量
uchar data dis_digit; //位选通值
uchar KeySec=0; //键值变量
void proc_key(); //触发
void inc_sec(); //秒
void inc_min(); //分
void inc_hour(); //时
void delay(uchar ms); //延时
void display1( uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6);//按位显示
void Timer0Init(); //初始化定时器0
void key_scan(); //按键扫描
void key_service(); //按键服务程序
void main(void)
{
P0 = 0xff; //初始化P0
P2 = 0xff; //初始化P2
Timer0Init(); //初始化定时器0
hour = 12; //初始化时
min = 00; //初始化分
sec = 00; //初始化秒
sec100 = 0; //初始化10ms计时变量
/****初始时钟显示 12 00 00 ****/
dis_buf[0] = hour / 10; // 时十位
dis_buf[1] = hour % 10; // 时个位
// dis_buf[2] = 0xbf; // 显示"-"
dis_buf[3] = min / 10; // 分十位
dis_buf[4] = min % 10; // 分个位
dis_buf[6] = sec / 10; // 秒十位
// dis_buf[5] = 0xbf; // 显示"-"
dis_buf[7] = sec % 10; // 秒个位
dis_digit = 0xfe;
dis_index = 0;
while(1)
{
key_service(); //按键服务程序
display1(dis_buf[0],dis_buf[1],dis_buf[3],dis_buf[4],dis_buf[6],dis_buf[7]);//按位显示
}
}
void timer0() interrupt 1 //定时器0中断服务程序
{
TL0 = 0x00; //重载定时初值
TH0 = 0xDC; //重载定时初值
key_scan(); //按键扫描程序
sec100++; //10ms变量自+1
if(sec100 >= 100)
{
sec100 = 0;
inc_sec();
}
}
void inc_sec() //秒计算
{
sec++;
if(sec > 59)
{
sec = 0; //秒自+1
inc_min(); //分计算
}
dis_buf[6] = sec / 10; // 秒十位
dis_buf[7] = sec % 10; // 秒个位
}
void inc_min() //分计算
{
min++;
if(min > 59)
{
min = 0;
inc_hour(); //时计算
}
dis_buf[3] = min / 10; // 分十位
dis_buf[4] = min % 10; // 分个位
}
void inc_hour() //时计算
{
hour++;
if(hour > 23) //
{
hour = 0;
}
if(hour > 9)
dis_buf[0] = hour / 10; // 时十位
else
dis_buf[0] = 0x00; // 当小时的十位为0时不显示
dis_buf[1] = hour % 10; // 时个位
}
void delay(uchar ms) // 延时子程序
{
uchar i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
void display1(uchar a1, uchar a2, uchar a3, uchar a4, uchar a5, uchar a6)//显示程序
{
dula=0;
P0=table[a1]; //显示时十位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
dula=0;
P0=table[a2]; //显示时个位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[a3]; //显示分十位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
P0=table[a4]; //显示分个位
dula=1;
dula=0;
P0=0x77;
wela=1;
wela=0;
delay(1);
P0=table[a5]; //显示秒十位
dula=1;
dula=0;
P0=0xef;
wela=1;
wela=0;
delay(1);
P0=table[a6]; //显示秒个位
dula=1;
dula=0;
P0=0xdf;
wela=1;
wela=0;
delay(1);
}
/**************************************************
初始化定时器程序 12T 10毫秒@11.0592MHz
**************************************************/
void Timer0Init() //10毫秒@11.0592MHz
{
// AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1; //开总中断
ET0=1; //开定时器0中断
}
/**************************************************
按键扫描程序
**************************************************/
void key_scan() //键扫描程序,放在中断里
{
static bit key1_sign,key2_sign; //静态-变量按键自锁标志变量
static uchar count1,count2; //静态-计数变量
if(K1==1) //检测按键1没有按下
{
key1_sign=0; //按键1自锁标志清0
count1=0; //消抖计数1清0
}
else //按键1按下
{
count1++; //消抖计数1自+1
if(count1>=2) //100次检测按键如果为0
{
if(key1_sign==0) //按键1自锁标志为0
{
key1_sign=1; //按键1自锁标志置1
KeySec=1; //输出键值1
}
}
}
if(K2==1) //检测按键2没有按下
{
key2_sign=0; //按键2自锁标志清0
count2=0; //消抖计数2清0
}
else //按键2按下
{
count2++; //消抖计数2自+1
if(count2>=2) //100次检测按键如果为0
{
if(key2_sign==0) //按键2自锁标志为0
{
key2_sign=1; //按键2自锁标志置1
KeySec=2; //输出键值2
}
}
}
}
/**************************************************
按键服务程序
**************************************************/
void key_service()
{
switch(KeySec) //按键服务状态切换
{
case 1: //事例1号键触发
inc_hour(); //时计算
KeySec=0; //键值清零,避免一直触发
break; //跳出当前程序
case 2: //事例2号键触发
min++;
if(min > 59) //分计算
{
min = 0;
}
dis_buf[3] = min / 10; // 分十位
dis_buf[4] = min % 10; // 分个位
KeySec=0; //键值清零,避免一直触发
break; //跳出当前程序
}
}