本帖最后由 雷影少年 于 2012-7-27 08:20 编辑
问题解决,把源码和电路图传上来给飞得比我慢的鸟儿们点虫吃,欢迎各位DX批评
0722.rar
(67.81 KB)
//////////////////////////////////////////////////////////////////////////////////////
程序写了几个小时,能够正常走时,就是调时的时候有的小问题,调试了N久实在没辙了请各位大神看看吧~
情况是这样,可以正常的走时,调时间的时候可以正常的加1,无抖动现象,但是在调位的时候,出现了点问题,
设定的是F键调整时钟状态,按1次调秒状态
按2次调分状态
按3次调时状态
按4次正常走时
但是现在按下F键不能确定被调的是时、分、秒还是正常走时,换了几个键都是这样,用proteus仿真也是如此,可以判定是我程序的问题
发源码
/***********************************************************
基于51定时器的时钟设计
利用LCD1602显示时间
具有调时、调分、调秒功能
F键调整时钟状态,按1次调秒状态
按2次调分状态
按3次调时状态
按4次正常走时
E键为add键,根据F的状态对应数值加1,
正常走时时E键无效
************************************************************/
#include<reg51.h>
typedef unsigned char u8;
typedef unsigned char u16;
#define ms_50 46080 //定义中断初始值
u8 date[] ={"DATE 2012-07-22 "}; //装载日期初始值
u8 time[] ={"TIME 23-59-50 "}; //装载时间初始值
u8 count;
u8 key_num; //时钟状态,
u8 key_add; //E键值
u8 hour =23;
u8 min =59;
u8 sec =50;
sbit lcdrs =P1^0;
sbit lcden =P1^1;
//延时程序
void delay(u8 x)
{
u8 a,b;
for (a =x;a>0;a--)
for (b =100;b>0;b--);
}
//向1602写命令
void write_com(u8 com)
{
lcdrs =0;
P2 =com;
delay(5);
lcden =1;
delay(5);
lcden =0;
}
//向1602内写数据
void write_date(u8 date)
{
lcdrs =1;
P2 =date;
delay(5);
lcden =1;
delay(5);
lcden =0;
}
//lcd初始化
void init()
{
lcden =0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
//显示初始时间
void display()
{
u8 num;
init();
write_com(0x80);
for (num =0;num<16;num++)
{
write_date(date[num]);
delay(3);
}
write_com(0x80+0x40);
for (num =0;num<16;num++)
{
write_date(time[num]);
delay(3);
}
}
//向1602内写入两位数(时间变化位)
void timer_dis(x)
{
write_com(0x80+0x40+x);
write_date(time[x]);
write_date(time[x+1]);
}
//键盘扫描程序
void key_saomiao()
{
u8 key,temp;
key_add =0; //add清零
/*****************扫描键盘**************/
P3 =0xf0;
temp =P3;
if((temp&0xf0)!=0xf0)
{
delay(100);
temp =P3;
if((temp&0xf0)!=0xf0)
{
P3 =0x0f;
temp =P3|temp;
}
}
switch(temp)
{
/* case 0xee: key =0;break;
case 0xed: key =1;break;
case 0xeb: key =2;break;
case 0xe7: key =3;break;
case 0xde: key =4;break;
case 0xdd: key =5;break;
case 0xdb: key =6;break;
case 0xd7: key =7;break;
case 0xbe: key =8;break;
case 0xbd: key =9;break;
case 0xbb: key =10;break;
case 0xb7: key =11;break;
case 0x7e: key =12;break;
case 0x7d: key =13;break;*/
case 0x7b: /*key =14;*/ key_add =1;break; //若E键按下,key_add置1
case 0x77: key =15;break;
default: key =0;
}
if(15 ==key) //判断F键按下
{
while(key) //等待按键松开
{
key_saomiao();
}
if(++key_num>=4 ) //key_num加1
{
key_num =0;
}
}
}
//键盘处理程序
void key_chuli()
{
key_saomiao(); //扫描键盘
if(key_add) //E键按下
{
while(key_add) //等待E键松开
{
key_saomiao();
}
switch(key_num) //判断时钟状态
{
case 1: //调秒
if(++sec>=60)
{
sec =0;
}
time[11] ='0'+sec/10; //更新数组数据
time[12] ='0'+sec%10;
timer_dis(11); //更新显示
break;
case 2: //调分
if(++min>=60)
{
min =0;
}
time[8] ='0'+min/10;
time[9] ='0'+min%10;
timer_dis(8);
break;
case 3: //调时
if(++hour>=24)
{
hour =0;
}
time[5] ='0'+hour/10;
time[6] ='0'+hour%10;
timer_dis(5);
break;
default: ;break;
}
}
}
//正常走时,更新时间
void timer()
{
/* static u8 hour =23;
static u8 min =59;
static u8 sec =50;*/
if (++sec>=60) //更新秒
{
sec =0;
if (++min>=60) //更新分
{
min =0;
if (++hour>=24) hour =0; //更新时
time[5] ='0'+hour/10; //更新显示
time[6] ='0'+hour%10;
timer_dis(5);
}
time[8] ='0'+min/10; //更新显示
time[9] ='0'+min%10;
timer_dis(8);
}
time[11] ='0'+sec/10; //更新显示
time[12] ='0'+sec%10;
timer_dis(11);
}
/**********************************************************
主函数
**********************************************************/
void main()
{
EA =1; //开中断
ET0 =1;
TMOD =0x01;
TH0 =-(ms_50/256); //装载定时器初始值
TL0 =-(ms_50%256);
TR0 =1;
display(); //显示初始时间
while (1)
{
key_saomiao(); //扫描键盘
while(key_num) //判断时钟是否处于调时状态状态
{
key_chuli(); //调用键盘处理程序
count =0;
}
if (count>=20) //正常走时,每秒更新一次时间
{
count =0;
timer();
}
}
}
//中断服务程序
void time50() interrupt 1 //每50ms中断一次
{
TH0 =-(ms_50/256);
TL0 =-(ms_50%256);
count++;
}
下面是图
|