天天看點

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;		 
	}
}
           

繼續閱讀