基于51单片机的秒表程序
基于51单片机的秒表程序
#include
sbitADDR3=P1^3;
sbitENLED=P1^4;
sbitKEY1=P2^4;
sbitKEY2=P2^5;
sbitKEY3=P2^6;
sbitKEY4=P2^7;//单片机I/O口
unsignedcharcodeLedChar[]={//数码管显示字符转换表
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};
unsignedcharLedBuff[6]={//数码管显示缓冲区
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
unsignedcharKeySta[4]={
1,1,1,1};
bitStopwatchRefresh=1;
bitStopwatchRunning=0;
unsignedcharDecimalPart=0;
unsignedintIntegerPart=0;
unsignedcharT0RH=0;
unsignedcharT0RL=0;
voidConfigTimer0(unsignedintms);
voidStopwatchDisplay();
voidKeyDriver();
voidmain()
{
EA=1;//使能总中断
ENLED=0;
ADDR3=1;
P2=0XFE;
ConfigTimer0(2);
while(1)
if(StopwatchRefresh)
{
StopwatchRefresh=0;
StopwatchDisplay();
}
KeyDriver();
}
}
voidConfigTimer0(unsignedintms)
{
unsignedlongtmp;
tmp=11059200/12;
tmp=(tmp*ms)/1000;
tmp=65536-tmp;
tmp=tmp+18;
T0RH=(unsignedchar)(tmp>>8);
T0RL=(unsignedchar)tmp;
TMOD&=0XF0;
TMOD|=0X01;
TH0=T0RH;
TL0=T0RL;
ET0=1;
TR0=1;
}
voidStopwatchDisplay()
{
signedchari;
unsignedcharbuf[4];
LedBuff[0]=LedChar[DecimalPart%10];
LedBuff[1]=LedChar[(DecimalPart/10)%10];
buf[0]=IntegerPart%10;
buf[1]=(IntegerPart/10)%10;
buf[2]=(IntegerPart/100)%10;
buf[3]=(IntegerPart/1000)%10;
for(i=3;i>=1;i--)
{
if(buf[i]==0)
LedBuff[i+2]=0XFF;
else
break;//高位消零
for(;i>=0;i--)
{
LedBuff[i+2]=LedChar[buf[i]];
}
LedBuff[2]&=0X7F;//第三个数码管显示小数点
}
//秒表开始函数
voidStopwatchAction()
{
if(StopwatchRunning)
StopwatchRunning=0;
else
StopwatchRunning=1;
}
//秒表复位函数
voidStopwatchReset()
{
StopwatchRunning=0;
DecimalPart=0;
IntegerPart=0;
StopwatchRefresh=1;
}
//检测按键是否有动作,主函数中调用此函数
voidKeyDriver()
{
unsignedchari;
staticunsignedcharbackup[4]={1,1,1,1};
for(i=0;i
{
if(backup[i]!=KeySta[i])
{
if(backup[i]!=0)
{
if(i==1)
StopwatchReset();
elseif(i==2)
StopwatchAction();
}
backup[i]=KeySta[i];
}
}
}
//按键扫描函数,需在定时中断中调用,推荐调用间隔1ms
voidKeyScan()
{
unsignedchari;
staticunsignedcharkeybuf[4]={0xFF,0xFF,0xFF,0xFF};
//将一行的4个按键值移入缓冲区
keybuf[0]=(keybuf[0]
keybuf[1]=(keybuf[1]
keybuf[2]=(keybuf[2]
keybuf[3]=(keybuf[3]
//消抖后更新按键状态
for(i=0;i
{
if(keybuf[i]==0x00)
{//连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
KeySta[i]=0;
}
elseif(keybuf[i]==0xFF)
{//连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
KeySta[i]=1;
}
}
}
//数码管显示函数,中断函数中调用
voidLedScan()
{
staticunsignedchari=0;
P0=0XFF;
P1=(P1&0XF8)|i;
P0=LedBuff[i];
if(i
i++;
else
i=0;
}
//秒表计数加函数
voidStopwatchCount()
{
if(StopwatchRunning)
{
DecimalPart++;
if(DecimalPart>=10)
{
DecimalPart=0;
IntegerPart++;
if(IntegerPart>=10000)
{
IntegerPart=0;
}
}
StopwatchRefresh=1;
}
}
/*T0中断服务函数,用于数码管显示扫描与按键扫描*/voidInterruptTimer0()interrupt1
{
staticunsignedchartmr10ms=0;
TH0=T0RH;
TL0=T0RL;
LedScan();
KeyScan();
tmr10ms++;
if(tmr10ms>=5)
{
tmr10ms=0;
StopwatchCount();
}
}