练习内容
注意:
1、按键的处理,当按键还未松开时,之前的做法是用个四循环(while(s4==0);)让程序停滞,在这里却不可以这样做,若在这单纯让程序停滞什么都不做,数码管将不能显示如何东西,因此可以在循环中不断扫描数码管(加入displaytime()这个函数),让数码管继续显示时间。
2、这里定义从左到右为第0~7位数码管。
具体代码
在这里插入代码片#include "reg52.h"
#include <intrins.h>
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};//0~F,“-”,“.”对应段码
//声明为“code”,节约ram区资源
sbit s4=P3^3;
sbit s5=P3^2;
unsigned char min=0;
unsigned char s=0;
unsigned char ms=0;
void displaytime();
void delayxms(unsigned int t) //@11.0592MHz
{
while(t--)
{
unsigned char data i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
void keyscan()
{
if(s4==0)//秒表启动与暂停
{
delayxms(10);
if(s4==0)
{
TR0=~TR0;
while(s4==0)
{
displaytime();
}
}
}
if(s5==0)//秒表清0
{
delayxms(10);
if(s5==0)
{
min=0;
s=0;
ms=0;
while(s5==0)
{
displaytime();
}
}
}
}
void hc573(unsigned char channel)
{
switch(channel)
{
case 4:P2=(P2&0x1f)|0x80;break;
case 5:P2=(P2&0x1f)|0xa0;break;
case 6:P2=(P2&0x1f)|0xc0;break;
case 7:P2=(P2&0x1f)|0xe0;break;
}
}
void displaysmg_bit(unsigned char val,unsigned char pos)//数码管位显示
{
hc573(6);
P0=0x01<<pos;//点亮指定位置的数码管
hc573(7);
P0=val;
}
void timer0_init()
{
TMOD=0x01;//选择模式
TH0=(65535-50000)/256;//设置初值
TL0=(65535-50000)%256;
ET0=1;
EA=1;
TR0=1;
}
void servicetimer0() interrupt 1
{
TH0=(65535-50000)/256;//重装,每0.05s中断一次
TL0=(65535-50000)%256;
ms++;
if(ms==20)
{
s++;
ms=0;
if(s==60)
{
min++;
s=0;
if(min==60)
{
min=0;
}
}
}
}
void displaytime()
{
displaysmg_bit(SMG_duanma[ms%10],7);//显示毫秒个位
delayxms(2);
displaysmg_bit(SMG_duanma[ms/10],6);
delayxms(2);
displaysmg_bit(SMG_duanma[16],5);
delayxms(2);
displaysmg_bit(SMG_duanma[s%10],4);//显示秒个位
delayxms(2);
displaysmg_bit(SMG_duanma[s/10],3);
delayxms(2);
displaysmg_bit(SMG_duanma[16],2);
delayxms(2);
displaysmg_bit(SMG_duanma[min%10],1);//显示分个位
delayxms(2);
displaysmg_bit(SMG_duanma[min/10],0);
delayxms(2);
}
void main()
{
timer0_init();
while(1)
{
displaytime();
keyscan();
}
}