循环流水加按键控制
实验设备
本次实验所用的设备如图: 由17个LED灯构成的一个心形灯,包括k1~k4四个按键 单片机型号:STC89C516 公司名称STC,8051内核,9指的是内部含Flash E2PROM,C指的是CMOS,16指片内ROM是64KB
最下方的灯是LED17,右侧是LED1-LED8,左侧是LED9-LED16
实验要求
按下k1,实现逆时针流水 按下k2,实现顺时针流水 按下 k3,流水暂停 按下k4,流水继续
思路分析
P2对应的是D1-D8灯,P0对应的是D9-D16灯,而P3的6口对应的是D17灯,所以要分成三部分,如何将三部分构成一个整体是重点。
解决办法:设置一个变量i,i从0一直到16,i是1的时候就是D17亮,依此类推,每个i对应一个灯亮,当亮完一圈之后,将i再置0.
按下k3,就需要设置标志位flag,如果flag等于1就是继续流水,flag=0就是在当前灯亮的位置停下,等待k4信号的来临接着流水。
注意:在流水的过程中,要时刻进行检测k3是否被按下,就需要check()函数,进行时刻调用。 最主要的就是当不满足条件时就会break,跳出相应的循环。
代码实现
#include<reg51.h>
#include<intrins.h>
void Delay(unsigned int i);
unsigned char Key(void);
void dispa();
void dispb();
void check();
sbit k1=P3^2;
sbit k2=P3^3;
sbit k3=P3^4;
sbit k4=P3^5;
sbit led=P3^6;
unsigned char flag=1;
unsigned char a;
unsigned char b;
void main()
{
unsigned char key;
key=Key();
switch(key)
{
case 1:
a=0xfe;
b=0x7f;
dispa();
if(k2==0)
{
a=0xfe;
b=0x7f;
dispb();
}
break;
case 2:
a=0xfe;
b=0x7f;
dispb();
if(k1==0)
{
a=0xfe;
b=0x7f;
dispa();
}
break;
default:
break;
}
}
void dispa()
{
unsigned int i=0;
while(1)
{ if(i==0)
{
P2=0xff;
P0=0xff;
led=0;
check();
if(k2==0)
{
break;
}
if(flag==0)
{
break;
}
Delay(1000);
led=1;
}
if(i%17<=8&&i%17>0)
{
P2=a;
check();
if(k2==0)
{
break;
}
if(flag==0)
{
break;
}
Delay(2000);
a=_crol_(a,1);
if(i==8)
{
P2=0xff;
}
}
if(i%17>8)
{
P0=b;
check();
if(k2==0)
{
break;
}
if(flag==0)
{
break;
}
Delay(2000);
b=_cror_(b,1);
}
i++;
if(i==17)
{
i=0;
}
}
}
void dispb()
{
unsigned int i=0;
while(1)
{ if(i==0)
{
P2=0xff;
P0=0xff;
led=0;
check();
if(k1==0)
{
break;
}
if(flag==0)
{
break;
}
Delay(2000);
led=1;
}
if(i%17<=8&&i%17>0)
{
P0=a;
check();
if(k1==0)
{
break;
}
if(flag==0)
{
break;
}
Delay(2000);
a=_crol_(a,1);
if(i%16==8)
{
P0=0xff;
}
}
if(i%17>8)
{
P2=b;
check();
if(k1==0)
{
break;
}
if(flag==0)
{
break;
}
Delay(2000);
b=_cror_(b,1);
}
i++;
if(i==17)
{
i=0;
}
}
}
void Delay(unsigned int i)
{
unsigned char j;
for(;i>0;i--)
{
for(j=110;j>0;j--);
}
}
unsigned char Key(void)
{
unsigned char key;
if(k1==0)
{
Delay(10);
if(k1==0)
{
key=1;
while(!k1);
}
}
if(k2==0)
{
Delay(10);
if(k2==0)
{
key=2;
while(!k2);
}
}
if(k3==0)
{
Delay(10);
if(k3==0)
{
key=3;
while(!k3);
}
}
if(k4==0)
{
Delay(10);
if(k4==0)
{
key=4;
while(!k4);
}
}
return key;
}
void check()
{
if(k3==0)
{
flag=0;
}
while(flag==0)
{
if(k4==0)
{
flag=1;
}
}
}
实验总结
在灯按下k1进行逆时针流水之后,如果流水的时候k2按下,那就要跳出当前循环进行顺时针流水,所以也要时刻检测k2是否为0;
灯和按键都是,当给一个低电平才会亮,才会有接通;
流水的方式采用的是循环移位,根据情况判断是左循环移还是右循环移。
|