STC学习:看谁手速快

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布布要成为最负责的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值