定时器实现秒表功能

练习内容

在这里插入图片描述
注意:
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();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值