实验目的:
K1-K4 控制 LED 移位:
按下 K1 时,P0 口 LED 上移一位;
按下 K2 时,P0 口 LED 下移一位;
按下 K3 时,P2 口 LED 上移一位;
按下 K4 时,P2 口 LED 下移一位
实验器材:
Protues、Keil
实验原理(给出硬件电路图):
实验步骤:
- 分析按键的原理,当按下按键的时候,按键的端口变为低电平;
- 根据要求和按键功能要进行程序代码
程序代码及实验结果(含汇编语言代码和C语言代码):
C语言:
#include<reg51.h>
#include<intrins.h>
void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
unsigned int t;
while(a--);
for(t=0;t<120;t++);
}
//主程序
void main()
{
unsigned char x;
x=0xff; //定义一个判断按键状态的变量
P0=0xfe; //P0为1111 1110,P0.0的LED灯亮
P2=0xfe;//P2为1111 1110 ,P2.0的LED灯亮
P1=0xff;//P1开始为1111 1111,四个按键没有按
while(1)
{
// 根 据 P1 口 的 按 键 移 动
if(x!=P1) //说明此时按键已经按下
{
x=P1; //把P1存起来
if ((P1&0x10)==0) P0=_cror_(P0,1); //当按下K1时,P1.4变为低电平,P1变为1110 0000,
//P1与0000 0001按位与,得到结果为0000 0000,if从句成立,开始上移P0端口的LED
else if((P1&0x20)==0) P0=_crol_(P0,1); //当按下K2时,P1.5变为低电平,P1变为1101 0000,
//P1与0000 0010按位与,得到结果为0000 0000,if从句成立,开始下移P0端口的LED灯
else if((P1&0x40)==0) P2=_cror_(P2,1);
//当按下K3时,P1.6变为低电平,P1变为1011 0000,
//P1与0000 0001按位与,得到结果为0000 0000,if从句成立,开始上移P2端口的LED灯
else if((P1&0x80)==0) P2=_crol_(P2,1); //当按下K4时,P1.7变为低电平,P1变为0111 0000,
//P1与0000 0001按位与,得到结果为0000 0000,if从句成立,开始上移P2端口的LED灯
}
}
}
汇编语言:
ORG 0000H
LJMP START
ORG 0030H
START:MOV P0,#0FEH
MOV P2,#0FEH
START0: ;判断按键是否按下
ACALL DELAY0 ;消抖是在延时完判断按键是否按下
MOV P1,#0FFH ;读P1口:首先向P1口送1,为读P1口做准备
MOV A,P1
CJNE A,#0FFH,JP1 ;判断是否有键按下
SJMP NEXT
JP1:;判断是哪个按键被按下
JNB ACC.4,LP1
JNB ACC.5,LP2
JNB ACC.6,LP3
JNB ACC.7,LP4
SJMP NEXT
LP1:MOV A,P0
RR A
MOV P0,A
SJMP NEXT
LP2:MOV A,P0
RL A
MOV P0,A
SJMP NEXT
LP3:MOV A,P2
RR A
MOV P2,A
SJMP NEXT
LP4:MOV A,P2
RL A
MOV P2,A
NEXT: ;确认按键是否释放
MOV P1,#0FFH
MOV A,P1 ;再读P1的引脚
CJNE A,#0FFH,NEXT ;确认键是否释放,若没释放,则等待键释放
SJMP START0
DELAY0:MOV R2,#70 ;20ms消抖子程序
D01: MOV R3,#100
D02: DJNZ R3,D02
DJNZ R2,D01
RET
END