电路图
要求
- 按下k1,led0~led7灯从上到下依次点亮,一直重复此状态
- 按下k2,led0~led7灯从下到上依次点亮,一直重复此状态
- 按下k3,led0~led3灯一起亮,与此同时led4 ~ led7处于熄灭状态,此状态交替出现
- 按下k4,led0~led7同亮同灭闪烁,一直重复此状态
条件
- P3的8个引脚低电平有效,P3.0~P3.7置0则led灯亮
- 按钮被按下时P1的某个引脚接地,该引脚电平为0(引脚置0,则按钮被按下)
完整程序
#include<reg51.h>
#include<intrins.h>
unsigned char flag;
unsigned char i;
sbit k1=P1^0;//键盘按钮k1
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
while(a--);
}
void flow1() //流水灯从上到下
{
P3=0xfe;//1111 1110
delay(30000);
for(i=1;i<=7;i++)
{
P3=_crol_(P3,1);//P3左移一位,例如P3=0x01 0000 0001 左移一位后0000 0010
delay(30000);//30000ms
}
}
void flow2() //流水灯从下到上
{
P3=0x7f;//0111 1111
delay(30000);
for(i=1;i<=7;i++)
{
P3=_cror_(P3,1);
delay(30000);//30000ms
}
}
void flow3()//led0~led3与led4~led7 交替亮灭
{
P3=0xf0;//led低电平有效 1111 0000 led0~led3亮
delay(30000);//30000ms
P3=0x0f;//led低电平有效 0000 1111 led4~led7亮
delay(30000);
}
void flow4() //led0~led7共同亮灭
{
P3=0x00;//led低电平有效 0000 0000 led0~led7全亮
delay(30000);//30000ms
P3=0xff;led低电平有效 1111 1111 led0~led7全灭
delay(30000);
}
void scan() //扫描按键状态
{
P1=0xff;//初始状态,k1~k4均未被按下
if( (P1 & 0x0f) != 0x0f )//P1前四个口分别接四个按键k1、k2、k3、k4,后四个口不接
{
delay(300);//按键消抖
//按位与&,P1=0xff & 0x0f 如果(1111 1111) & (0000 1111) = 0000 1111,则P1状态未发生改变
if( (P1 & 0x0f) != 0x0f )//消抖后再次检查按键状态
{
if(k1==0) //按键k1被按下,P1=
flag=1;
if(k2==0) //按键k2被按下
flag=2;
if(k3==0) //按键k3被按下
flag=3;
if(k4==0) //按键k4被按下
flag=4;
}
}
}
void main()
{
while(1)
{
flag=0;//初始化flag
P3=0xff;//led低电平有效,初始状态1111 1111,led0~led7全部灭
scan();//扫描键盘,如果有按键被按下,则会得到一个flag值
switch(flag)
{
case 1:flow1();break;
case 2:flow2();break;
case 3:flow3();break;
case 4:flow4();break;
}
}
}
程序中涉及的部分内容
- 按键消抖
- 按位与( & )运算
if( (P1 & 0x0f) != 0x0f )//下图不满足if中的条件
未有任何按键被按下时:
例如:当按键k1被按下时(k1等于0)
if( (P1 & 0x0f) != 0x0f )//下图满足if中的条件,(P1 & 0x0f)的结果不再是0x0f,即有按键被按下