天天看点

C51学习笔记:基于STC89C52的数码管秒表设计

昨天同学问我能不能帮他做道题,有关单片机定时器的,我大概写了一个小时把这道题完成了,写这篇博客记录练习和学习的历程。

使用的是普中科技的A2开发板。

题目

数码管秒表设计

任务1,能够操作数码管显示任意数字

任务2,在数码管的第1、2位显示秒数,第3位显示“-”,第4位显示1/10秒,第5位显示1/100秒。

任务3,按下独立按键K1后,秒表开始计时,再次按下独立按键K1后,秒表停止,按下独立按键K2后,秒表计数清零。

分析: 完成这个题目需要运用中断、独立键盘和数码管的相关知识。

我的代码

#include"reg52.h"

typedef unsigned int u16; //偷懒
typedef unsigned char u8;

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管显示0-9的段选的数值

int sec;  //定义秒变量
int msec; //定义毫秒变量
int count;//定义计时器溢出变量
					
sbit LSA=P2^2; //定义数码管位选的引脚
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit k1=P3^1;  //定义独立键盘的引脚
sbit k2=P3^0;

/*
名称:delay
作用:延时
*/
void delay(u16 z)  

{
	u16 x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
	

/*
名称:sec_display
作用:数码管上秒的十位和个位数的显示
*/
void sec_display(int second)

{
	LSA=1;//数码管位选,下皆同
	LSB=1;
	LSC=1;
	P0=smgduan[second/10];//显示秒的十位
	delay(10);
	//短暂延时,下同,在这里延时的时间越短,刷新的频率越高,看起来数码管闪烁的程度就越弱
	P0=0x00;//消隐,下同
	LSA=0;
	LSB=1;
	LSC=1;
	P0=smgduan[second%10];
	delay(10);
	P0=0x00;
}


/*
名称:mirco_display
作用:数码管上1/10秒和1/100秒的显示
*/
void mirco_display(int x)
	
{
	msec=x*50;//count加1,大约是50ms,这里x是后面输入的count
	LSA=0;
	LSB=0;
	LSC=1;
	P0=smgduan[msec/100];
	delay(10);
	P0=0x00;
	LSA=1;
	LSB=1;
	LSC=0;
	P0=smgduan[msec%100/10];
	delay(10);
	P0=0x00;
}


/*
名称:sta_display
作用:数码管上分隔符"-"的显示
*/
void sta_display()
	
{
	LSA=1;
	LSB=0;
	LSC=1;
	P0=0x40;
	delay(10);
	P0=0x00;
}


/*
名称:init
作用:定时器初始化,包括:确定定时器工作方式,打开总中断,装入初始值等,但是在这里定时器0一开始是关闭的,对应题目要求的按下键盘才开始计时
*/
void init()
	
{
	TMOD=0x01;	 //确定定时器工作方式
	EA=1;		 //打开总中断
	ET0=1;		 
	TR0=0;		 //关闭定时中断0
	TH0=(65536-50000)/256;	 //装入初始值
	TL0=(65536-50000)%256;
}


/*
名称:keyscan
作用:键盘检测,使用循环扫描的方式来检测是否有按键输入
*/
void keyscan()
	
{
	if(k1==0)   //检测到按键1按下
	{
		delay(50);  //短暂延时,消除抖动
		if(k1==0)
		{
			TR0=~TR0;  //定时器状态取反,按下一次是打开,再按一次是关闭
			while(!k1);//检测到松手
		}
	}
	if(k2==0)    //检测到按键2按下
	{
		delay(50); //短暂延时,消除抖动
		if(k2==0)
		{
			count=0;//数值归零,以达到显示归零的效果
			sec=0;
			while(!k2);//检测到松手
		}
	}
}



/*
名称:主函数
作用:程序的主体
*/
void main()

{
	init();//初始化
	while(1)//进入死循环
		{
			keyscan();
			sta_display();
			sec_display(sec);
			mirco_display(count);
		}
}



/*
名称:timer0
作用:定时器中断
*/
void timer0() interrupt 1  

{
	TH0=(65536-50000)/256;//装入初始值	  
	TL0=(65536-50000)%256;
	count++;			//约50ms,count加1
	if(count==20)		//count加20次,即1000ms=1s,秒加一
	{
		count=0;		//count归零
		sec++;			
		if(sec==60)		//当s到达60,s归零
			sec=0;		 
	}
}
           

继续阅读