51 AutoLeaders控制组——51单片机TASK1

基础练习:

1)通过数码管显示当前模式

2)通过独立按键进行模式切换

整体功能介绍:

通过按键 S1,S2,S3,S4 能够控制 89C52RC 单片机的工作模式,每次按下 S1 按键时,单

片机进入模式一;按下 S2 按键时,单片机进入模式二;按下 S3 按键时,单片机进入模式三;

按下 S4 按键时,单片机进入模式四。

四个不同的模式下,89c52 单片机的数码管和 LED 灯有不同的工作状态。

模式 1

当按下独立按键 S1 的时候,左边四个 LED 与右边四个 LED 交替亮灭

模式 2

U2▢▢▢▢02

模式 3

U3▢▢▢▢XX

(其中XX为计时器,要求00-10依次显示)

模式 4

(原为模式三基础上要求LED流水灯)

独立按键控制LED流水灯开关

任务完成记录

模式一

模式一要求左边四个 LED 与右边四个 LED 交替亮灭,只需设置四个LED亮而另外四个灭,设置Delay函数延迟,再P2取反,循环即可

模式二

模式二要求使用数码管显示,由于是静止显示,只需依次编写各个数码管所需显示的字母或数字即可。

模式三

模式三要求数码管最后两位起计时器的作用,要求以1s的频率依次显示00-10

重点在于1s的把控以及最后两个数码管在第10秒时的数字显示(即第7位显示1,第8位清零)

STC89C52RC的晶振频率为11.0592MHz,即每秒震荡11.0592 * 1 000 000次(11.0592百万次)

12分频后得到每秒有921600个时间周期

每次扫描数码管大约需要1000个时间周期,每次需要扫描4个数码管,那么我们可以得到每秒的扫描次数(921600 / 1000 / 4 = 230.4次)

那么我们可以通过计算扫描次数来得到大致一秒的时间

(以上来自学长总结的简单总结)

模式四

模式四为独立按键控制LED流水灯开关,只需使用P2=~(0x00<<num)即可完成LED灯亮的移动,重点在于按下按键可以控制模式的开关。我们需要判断按键是否再次被按下,以此控制模式的关闭。我们可以命名ledon=1为开,在按键重新被按下时对ledon进行取反,从而关闭LED流水灯。用if编写流水灯的代码即可,可以用delay函数控制流水灯的速度。

需要注意的是,当用按键重新开启LED流水灯时,流水灯会从上次停止的地方重新出发,我们可以在重新开启时令num=0,即可使LED流水灯从头开始。

代码实现

#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E};
unsigned char cnt=0,num1=0,num2=0,num3=0;////0, 1, 2, 3, 4, 5, 6, 7, 8, 9, U, -对应的段码

bit ledon = 1;//模式4中LED流水灯开启状态,1表示开,0表示关

unsigned char alonekey_num;

void Delay(unsigned int xms)	//@11.0592MHz
{
	unsigned char data i, j;
	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

unsigned char alonekey(void)//按键消抖
{
	unsigned char alonekey_num=0;
	if(P3_1==0){alonekey_num=1;}
	if(P3_0==0){alonekey_num=2;}
	if(P3_2==0){alonekey_num=3;}
	if(P3_3==0){alonekey_num=4;}
	return alonekey_num;
}

void alonekey_loop(void)
{
	static unsigned char before_num=0,now_num=0;
	before_num=now_num;
	now_num=alonekey();
	if(before_num!=now_num)
	{
		Delay(20);
	}
	if(before_num!=0 && now_num==0)
	{
		alonekey_num=before_num;
	}
}

void Nixie(unsigned char Location,Number)//分别传入显示位置、显示内容
{
	switch(Location)//选择显示位置
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];
	Delay(1);
	P0=0x00; 
}


void main()
{	
	while(1)
	{	
		alonekey();
		alonekey_loop();
		switch(alonekey_num)
		{
			case 1:
				P2=0xF0;
				Delay(300);
				P2=~P2;
				Delay(300);
				break;
			
			case 2:
				Nixie(1,10);
				Nixie(2,2);
				Nixie(7,0);
				Nixie(8,2);
				break;

			case 3:
				cnt=0;
				while(cnt<=230){
					cnt++;
					Nixie(1,10);
					Nixie(2,3);
					Nixie(7,0);
					Nixie(8,num1);
					
					if(cnt==230){
						num1++;
						if(num1==10){
							cnt=0;
							num1=0;
							while(cnt<=230){
								cnt++;
								Nixie(1,10);
								Nixie(2,3);
								Nixie(7,1);
								Nixie(8,0);
							}
						}
					}
				}
				break;
				
			case 4:
					if(P3_3==0){  //再次检测按键状态
						while(P3_3==0);
						ledon = !ledon; // 切换流水灯状态
					}
					if(ledon){
					P2=~(0x01<<num3);
					Delay(100);
					num3++;
					if(num3>=8){
						num3=0; //如果流水灯重新开启,则重置num3为0,从头开始
					}
				}else{
					P2=~0x00; // 流水灯关闭,所有LED熄灭
				}
				break;
		}				
	}
}

​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值