简单电子表
时间:10-02
整理:3721RD
点击:
最近学习51单片机,自己写了一个简单的电子表程序,但是总觉得还有些问题,是否还有更好的解决方案。由于目前才学到定时器这里,希望大虾能批评指正,通过仿真的时候,发现,有时候按键感觉处于失灵的状态,但是如果按的时间长一点,再松开就不不会出现,请问这应该是什么原因呢?代码如下:
/************************此文件已编译通过***************************************************************/
//1,可实现24小时计时
//2,可以通过按键手动校准当前时间
/******************************************************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit K1=P3^4;
sbit K2=P3^5;
sbit K3=P3^6;
sbit K4=P3^7;
sbit LE1=P2^6;
sbit LE2=P2^7;
/*函数声明*************************************************************/
void s_jian_z();
void xian_s();
void delay_xms(uchar);
void key_scan();
void chu_s();
/********************************************************************/
uchar code d_ma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar num=0;f_num=0;s_num=0;
uchar num0;
uchar m_shi,m_ge,f_shi,f_ge,s_shi,s_ge;
uint s_f_k1=0;
/*初始化函数*********************************************************/
void chu_s()
{
TMOD=0x10;
EA=1;
ET1=1;
}
/*延时函数*************************************************************/
void delay_xms(uchar xms)
{ uchar i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
/*时间附值函数*********************************************************/
void s_jian_z()
{
if( num0==20)
{
num0=0;
num++;
}
if(num==60)
{
num=0;
f_num++;
}
if(f_num==60)
{
f_num=0;
s_num++;
}
if(s_num==24)
s_num=0;
}
/*键盘扫描函数*********************************************************/
void key_scan()
{
if(K1==0&&s_f_k1==2) //按下三次k1时间设定完成
{
delay_xms(10);
if(K1==0)
s_f_k1=0;
while (!K1);
}
if(K1==0&&s_f_k1==1)
{
delay_xms(10);
if(K1==0)
s_f_k1=2; //表示k1按下两次 ,可以改变时间的分钟设定新值
while(!K1);
}
if(K1==0)
{
delay_xms(10);
if(K1==0)
s_f_k1=1; //表示k1按下一次 ,可以改变时间的小时设定新值
while(!K1);
}
if(s_f_k1==1)
{
if(K2==0) //表示k1按下之后,按下k2,小时加1
{
delay_xms(10);
if(K2==0)
{
s_num++;
if(s_num==24)
s_num=0;
}
while(!K2);
}
else if (K3==0) //表示按下k1之后,按下k3,小时减1
{
delay_xms(10);
if(K3==0)
{
if(s_num==0)
s_num=24;
s_num--;
}
while(!K3);
}
}
if(s_f_k1==2)
if(K2==0) //表示按下k1两次,按下k2分钟加1
{
delay_xms(10);
if(K2==0)
{
f_num++;
if(f_num==60)
f_num=0;
while(!K2);
}
}
else if (K3==0) //表示k1按下两次,这次按下k3分钟减1
{
delay_xms(10);
if(K3==0)
{
if(f_num==0)
f_num=60;
f_num--;
while(!K3);
}
}
if(K4==0) //按下k4,启动或者关闭定时器
{
delay_xms(10);
if(K4==0)
TR1=~TR1;
while(!K4);
}
}
/*扫描显示函数**********************************************************/
void xian_s( )
{
s_jian_z();
m_shi = num/10;
m_ge =num%10;
f_shi =f_num/10;
f_ge =f_num%10;
s_shi =s_num/10;
s_ge =s_num%10;
/**间隔点的显示***************************************************************/
LE2=1;
P0=0xdb;
LE2=0;
P0=0xff;
delay_xms(5);
LE1=1;
P0=0x80;
LE1=0;
P0=0xff;
delay_xms(5);
/**小时十位的显示************************************************/
LE2=1;
P0=0xfe;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[s_shi];
LE1=0;
delay_xms(5);
P0=0xff;
/***小时个位的显示***************************************************/
LE2=1;
P0=0xfd;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[s_ge];
LE1=0;
delay_xms(5);
P0=0xff;
/***分钟十位的显示****************************************************/
LE2=1;
P0=0xf7;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[f_shi];
LE1=0;
delay_xms(5);
P0=0xff;
/****分钟个位的显示*************************************************/
LE2=1;
P0=0xef;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[f_ge];
LE1=0;
delay_xms(5);
P0=0xff;
/***秒十位的显示***********************************************/
LE2=1;
P0=0xbf;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[m_shi];
LE1=0;
delay_xms(5);
P0=0xff;
/****秒个位的显示****************************************/
LE2=1;
P0=0x7f;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[m_ge];
LE1=0;
delay_xms(5);
P0=0xff;
}
/****主函数*******************************************************/
void main()
{
chu_s();
while(1)
{
key_scan(); //检测键盘
if(!s_f_k1) //当调节时间的时候数码管处于闪烁状态
xian_s(); //显示内容
else
while(1)
{
LE2=1;
P0=0xff;
LE2=0;
delay_xms(200);
delay_xms(200);
delay_xms(200);
delay_xms(200);
delay_xms(200);
delay_xms(200);
xian_s(); //显示内容
break;
}
}
}
/*中断函数****************50ms中断一次**************************************/
void T1_time() interrupt 3
{
TH1=0x3c;
TL1=0xb0;
num0++;
}
/************************此文件已编译通过***************************************************************/
//1,可实现24小时计时
//2,可以通过按键手动校准当前时间
/******************************************************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit K1=P3^4;
sbit K2=P3^5;
sbit K3=P3^6;
sbit K4=P3^7;
sbit LE1=P2^6;
sbit LE2=P2^7;
/*函数声明*************************************************************/
void s_jian_z();
void xian_s();
void delay_xms(uchar);
void key_scan();
void chu_s();
/********************************************************************/
uchar code d_ma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar num=0;f_num=0;s_num=0;
uchar num0;
uchar m_shi,m_ge,f_shi,f_ge,s_shi,s_ge;
uint s_f_k1=0;
/*初始化函数*********************************************************/
void chu_s()
{
TMOD=0x10;
EA=1;
ET1=1;
}
/*延时函数*************************************************************/
void delay_xms(uchar xms)
{ uchar i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
/*时间附值函数*********************************************************/
void s_jian_z()
{
if( num0==20)
{
num0=0;
num++;
}
if(num==60)
{
num=0;
f_num++;
}
if(f_num==60)
{
f_num=0;
s_num++;
}
if(s_num==24)
s_num=0;
}
/*键盘扫描函数*********************************************************/
void key_scan()
{
if(K1==0&&s_f_k1==2) //按下三次k1时间设定完成
{
delay_xms(10);
if(K1==0)
s_f_k1=0;
while (!K1);
}
if(K1==0&&s_f_k1==1)
{
delay_xms(10);
if(K1==0)
s_f_k1=2; //表示k1按下两次 ,可以改变时间的分钟设定新值
while(!K1);
}
if(K1==0)
{
delay_xms(10);
if(K1==0)
s_f_k1=1; //表示k1按下一次 ,可以改变时间的小时设定新值
while(!K1);
}
if(s_f_k1==1)
{
if(K2==0) //表示k1按下之后,按下k2,小时加1
{
delay_xms(10);
if(K2==0)
{
s_num++;
if(s_num==24)
s_num=0;
}
while(!K2);
}
else if (K3==0) //表示按下k1之后,按下k3,小时减1
{
delay_xms(10);
if(K3==0)
{
if(s_num==0)
s_num=24;
s_num--;
}
while(!K3);
}
}
if(s_f_k1==2)
if(K2==0) //表示按下k1两次,按下k2分钟加1
{
delay_xms(10);
if(K2==0)
{
f_num++;
if(f_num==60)
f_num=0;
while(!K2);
}
}
else if (K3==0) //表示k1按下两次,这次按下k3分钟减1
{
delay_xms(10);
if(K3==0)
{
if(f_num==0)
f_num=60;
f_num--;
while(!K3);
}
}
if(K4==0) //按下k4,启动或者关闭定时器
{
delay_xms(10);
if(K4==0)
TR1=~TR1;
while(!K4);
}
}
/*扫描显示函数**********************************************************/
void xian_s( )
{
s_jian_z();
m_shi = num/10;
m_ge =num%10;
f_shi =f_num/10;
f_ge =f_num%10;
s_shi =s_num/10;
s_ge =s_num%10;
/**间隔点的显示***************************************************************/
LE2=1;
P0=0xdb;
LE2=0;
P0=0xff;
delay_xms(5);
LE1=1;
P0=0x80;
LE1=0;
P0=0xff;
delay_xms(5);
/**小时十位的显示************************************************/
LE2=1;
P0=0xfe;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[s_shi];
LE1=0;
delay_xms(5);
P0=0xff;
/***小时个位的显示***************************************************/
LE2=1;
P0=0xfd;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[s_ge];
LE1=0;
delay_xms(5);
P0=0xff;
/***分钟十位的显示****************************************************/
LE2=1;
P0=0xf7;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[f_shi];
LE1=0;
delay_xms(5);
P0=0xff;
/****分钟个位的显示*************************************************/
LE2=1;
P0=0xef;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[f_ge];
LE1=0;
delay_xms(5);
P0=0xff;
/***秒十位的显示***********************************************/
LE2=1;
P0=0xbf;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[m_shi];
LE1=0;
delay_xms(5);
P0=0xff;
/****秒个位的显示****************************************/
LE2=1;
P0=0x7f;
LE2=0;
delay_xms(5);
P0=0xff;
LE1=1;
P0=d_ma[m_ge];
LE1=0;
delay_xms(5);
P0=0xff;
}
/****主函数*******************************************************/
void main()
{
chu_s();
while(1)
{
key_scan(); //检测键盘
if(!s_f_k1) //当调节时间的时候数码管处于闪烁状态
xian_s(); //显示内容
else
while(1)
{
LE2=1;
P0=0xff;
LE2=0;
delay_xms(200);
delay_xms(200);
delay_xms(200);
delay_xms(200);
delay_xms(200);
delay_xms(200);
xian_s(); //显示内容
break;
}
}
}
/*中断函数****************50ms中断一次**************************************/
void T1_time() interrupt 3
{
TH1=0x3c;
TL1=0xb0;
num0++;
}
仿真图
因为你的按键程序没有去抖动,所以按键会失灵。你应该用2~10s的时间来去按键抖动,按键程序是
判断按键是否按下——延时8s——再判断按键是否被按下,判断按键是否按下后弹起也一样。
按键失灵的原因是你的按键扫描调用延时过长。建议把键盘扫描程序同时放到第二个while(1)里面去
在哪一步失灵的,是哪个按键失灵?晶振是多少,延时程序延时量是多少?看了一下,像2楼分析的原因,不是失灵
太感谢啦,很好用
消抖!
抖动消除木有,缺憾。