程序设计目标及程序运行效果说明
程序设计目标:综合使用蜂鸣器、数码管、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();
}
}