程式設計目标及程式運作效果說明
程式設計目标:綜合使用蜂鳴器、數位管、LED燈和按鍵Key1,設計在固定時間内,記下按鍵key1按下的次數,并顯示在數位管上。
程式運作效果說明:
(1) 按下Reset,8個LED燈全部點亮,作為預備信号;之後蜂鳴器發出響聲,作為開始信号;
(2) 在開始之後,不斷按下Key1,數位管上顯示的個數不斷增加,同時led從左到右逐個亮起,作為時間信号。
(3) 當led從左至右亮完之後,時間停止,此時按下Key1數位管不再加1;數位管上顯示的個數即在規定時間内,按下Key1的次數。
程式相關電路及工作原理說明
1.LED數位管電路

2.蜂鳴器電路
3.按鍵電路
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();
}
}