带键盘设置的秒计时器
;功能:倒计时的秒计时器,从59倒计到0,然后又从59开始倒计到0;
;各个键的功能
;S1:开始运行
;S2:停止运行
;S3:高位加1,按一次,数码管的十位加1,从0-5循环变化
;S4:低位加1,按一次,数码管的个位加1,从0-9循环变化
;本例可用ledkey.dll实验仿真板验证
;如使用DSB-1A型实验板,将提供相应的程序
**************************************************/
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
#define Hidden 0x10; //消隐字符在字形码表中的位置
uchar code BitTab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};
uchar DispBuf[8]; //6字节的显示缓冲区
bit Sec; //1s到的标记
uchar SecVal; //秒计数值
bit KeyOk;
bit StartRun;
uchar SetSecVal; //秒的预置值
uchar code TH0Val=63266/256;
uchar code TL0Val=63266%256;//当晶振为11.0592时,定时2.5ms的定时器初值
//经过精确调整,在值为63266时,定时时间为1.00043362s
void Timer0() interrupt 1
{ uchar tmp;
static uchar dCount; //计数器,显示程序通过它得知现正显示哪个数码管
static uint Count; //秒计数器
const uint CountNum="100"; //预置值(正确值为400)
TH0=TH0Val;
TL0=TL0Val;
tmp=BitTab[dCount]; //根据当前的计数值取位值
P2=P2|0xff; //P2与11111100B相或,将高6位置1
P2=P2&tmp; //P2与取出的位值相与,将某一位清零
tmp=DispBuf[dCount]; //根据当前的计数值取显示缓冲待显示值
tmp=DispTab[tmp]; //取字形码
P0=tmp; //送出字形码
dCount++; //计数值加1
if(dCount==8) //如果计数值等于6,则让其回0
dCount=0;
//以下是秒计数的程序行
Count++; //计数器加1
if(Count>=CountNum) //到达预计数值
{ Count=0; //清零
if(StartRun) //要求运行
{ if((SecVal--)==0)
SecVal=SetSecVal; //减到0后重置初值
}
}
}
/*延时程序
由Delay参数确定延迟时间
*/
void mDelay(unsigned int Delay)
{ unsigned int i;
for(;Delay>0;Delay--)
{ for(i=0;i<124;i++)
{;}
}
}
void KeyProc(uchar KValue) //键值处理
{ if((KValue&0x10)==0) //Start
StartRun=1;
if((KValue&0x20)==0) //Stop
StartRun=0;
if((KValue&0x40)==0)
{ StartRun=0; //停止运行
DispBuf[6]++;
if(DispBuf[6]>=6) //次高位由0加到5
DispBuf[6]=0;
SetSecVal=DispBuf[6]*10+DispBuf[7]; //计算出设置值
SecVal=SetSecVal;
}
if((KValue&0x80)==0)
{ StartRun=0; //停止运行
DispBuf[7]++;
if(DispBuf[7]>=10) //末位由0加到9
DispBuf[7]=0;
SetSecVal=DispBuf[6]*10+DispBuf[7]; //计算出设置值
SecVal=SetSecVal;
}
}
uchar Key()
{ uchar KValue;
uchar tmp;
P1|=0xf0; //将P3口的接键盘的中间四位置1
KValue=P1;
KValue|=0x0f; //将未接键的4位置1
if(KValue==0xff) //中间4位均为1,无键按下
return(0); //返回
mDelay(10); //延时10ms,去键抖
KValue=P1;
KValue|=0x0f; //将未接键的4位置1
if(KValue==0xff) //中间4位均为1,无键按下
return(0); //返回
//如尚未返回,说明一定有1或更多位被按下
for(;;)
{ tmp=P1;
if((tmp|0x0f)==0xff)
break; //等待按键释放
}
return(KValue);
}
void Init()
{ TMOD=0x01;
TH0=TH0Val;
TL0=TL0Val;
ET0=1; //开T0中断
EA=1; //开总中断
TR0=1; //T0开始运行
}
void main()
{ uchar KeyVal;
uchar i;
Init(); //初始化
for(i=0;i<=6;i++)
DispBuf=Hidden; //显示器前四位消隐
DispBuf[6]=SecVal/10;
DispBuf[7]=SecVal%10;
for(;;)
{ KeyVal=Key();
if(KeyVal)
KeyProc(KeyVal);
DispBuf[6]=SecVal/10;
DispBuf[7]=SecVal%10;
}
}
文章评论(0条评论)
登录后参与讨论