天天看點

STC學習:看誰手速快

程式設計目标及程式運作效果說明

程式設計目标:綜合使用蜂鳴器、數位管、LED燈和按鍵Key1,設計在固定時間内,記下按鍵key1按下的次數,并顯示在數位管上。

程式運作效果說明:

(1) 按下Reset,8個LED燈全部點亮,作為預備信号;之後蜂鳴器發出響聲,作為開始信号;

(2) 在開始之後,不斷按下Key1,數位管上顯示的個數不斷增加,同時led從左到右逐個亮起,作為時間信号。

(3) 當led從左至右亮完之後,時間停止,此時按下Key1數位管不再加1;數位管上顯示的個數即在規定時間内,按下Key1的次數。

程式相關電路及工作原理說明

1.LED數位管電路

STC學習:看誰手速快

2.蜂鳴器電路

STC學習:看誰手速快

3.按鍵電路

STC學習:看誰手速快

4.工作原理

在此案例中,對按鍵key1的處理有比較高的要求,需要對key1消抖,防止按鍵之後增加資料不穩定。

同時要注意适可使數位管顯示清除的資料,防止有殘影和不顯示的現象。

代碼如下:

#include<STC15F2K60S2.H>
#define uchar unsigned char
#define uint unsigned int
uchar code duanxuan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  
uchar code weixuan[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
#define NMAX_KEY 100  //100次讀取按鍵值
sbit led_sel=P2^3;
sbit beep=P3^4;
sbit Key1=P3^2;
uint Key1_count;
uint Key_count;
bit Key1_C;/*key1目前的狀态*/
bit Key1_P;/*key1前一個狀态*/
uint num;						//按鍵次數
uint counter;
uchar led_i;
bit beep_flag;
bit star_flag;
bit end_flag;
void delayMs(uint Ms)			
{
	uint i;
	for(;Ms>0;Ms--)
		for(i=120;i>0;i--);
}
void Led_show()//LED燈顯示
{
	led_sel=1;
	P0=0x00;
	switch(led_i)
	{
		case 0:P0=0x01;break;
		case 1:P0=0x03;break;
		case 2:P0=0x07;break;
		case 3:P0=0x0f;break;
		case 4:P0=0x1f;break;
		case 5:P0=0x3f;break;
		case 6:P0=0x7f;break;
		case 7:P0=0xff;break;
		default:star_flag=0;end_flag=1;break;		//把star置0,end置1,使在main中停止中斷
	}
}
void shumaguan_show()//數位管後三位動态顯示按鍵次數
{	
	static uchar w=7;
	led_sel=0;
	P0=0x00;
	switch(w)
	{
		case 7:P2=weixuan[w--];P0=duanxuan[num%10];break;
		case 6:P2=weixuan[w--];P0=duanxuan[(num/10)%10];break;
		case 5:P2=weixuan[w];P0=duanxuan[num/100];w=7;break;
	}
}
void Init()//定時器、蜂鳴器和參數的初始化
{
	P0M1=0x00;
	P0M0=0xff;
	P2M1=0x00;
	P2M0=0x08;
	P3M0=0x10;
	P3M1=0x00;		//設定推挽模式
	led_sel=1;		//選中Led燈
	beep=0;			//置零,保護蜂鳴器
	P0=0xff;			//led燈全亮,預備信号,等待蜂鳴器聲響
	TMOD&=0xf0;
	TMOD|=0x01;		//設定定時器0,定時方式1,16位手動重裝模式
	TH0=0xfc;			
	TL0=0x17;			//設定定時器0初值
	delayMs(5000);		//預備時間設定為5秒
	ET0=1;			//打開定時器0中斷
	TR0=1;			//打開定時器0,開始工作
	EA=1;				//打開總中斷
	counter=0;
	num=0;
	beep_flag=1;
	end_flag=0;
	star_flag=0;
}
void main()
{
	Init();
	while(1)
	{
		if(star_flag==1)	
		{
			if(Key1==0)
			   Key1_count--;
			Key_count--;//總的次數減1
			if(Key_count==0)//100次完了
			{
				if(Key1_count<0x80)
				{
					Key1_C=0;
					if(Key1_P==1)	//下降沿(按鍵做動作)
					{
						Key1_P=0;
						num++;
					}
				}
				if(Key1_count>=0x80)
				{
					Key1_C=1;
					if(Key1_P==0)
					   Key1_P=1;	//上升沿(假設不做動作那就繼續)
				}
				/*新一輪的判斷*/
				Key1_count=0x80+NMAX_KEY/3*2;
				Key_count=NMAX_KEY;
			}
		}
		else if(end_flag==1)
		{
			ET0=0;
			TR0=0;
			shumaguan_show();
		}
	}
}
//控制數位管和Led燈交替動态顯示
void time0()interrupt 1
{
	TH0=0xfc;
	TL0=0x17;		
	counter++;
	if(beep_flag==1)beep=~beep;
	if(counter==100){beep_flag=0;star_flag=1;}//定時器前100毫秒用來控制蜂鳴器,100毫秒後遊戲開始
	if(counter>100)
	{
		led_i=(counter-100)/1000;						//流水燈頻率為1秒,每秒led_i加1
		if((counter%8)>3)							    //數位管顯示
			shumaguan_show();
		else											//Led燈顯示
			Led_show();
	}
}
           

繼續閱讀