实验3 基于51单片机的按键控制系统设计

目录

一、实验项目

二、实验目的

三、实验器材

四、实验原理(含硬件电路图)

五、实验步骤

六、程序代码

1.C语言代码:

2.汇编语言代码:


一、实验项目:按键控制系统设计

二、实验目的

        本系统设计的目的是使学生掌握单片机的接口按键输入技术。深刻理解单片机片内主要硬件的功能和运行原理,掌握单片机软硬件系统开发的技巧。具体要求用单片机控制两列LED,每列有8只LED,分别接受4个按键K1-K4的控制。当K1按下时,左列LED向.上移位;K2按下时,左列LED向下移位; K3按下时,右列LED向上移位; K4按下时,右列LED向下移位;要求在Proteus中设计出仿真硬件电路,在keil uvision中分别设计出汇编语言和C语言的源程序,然后用Proteus来进行整体系统仿真运行。

三、实验器材

        电脑,Keil uVision编译器Proteus电路仿真软件。

        实验模拟的各器件:AT89C51单片机、 CAP电容、 CAP-ELEC锁存器、 CRYSTAL震荡器、16只灯泡(具有不同的颜色)、 RES电阻、四个按键控制。

四、实验原理(含硬件电路图)

        本实验涉及单片机的接口按键输入技术。接口按键是指通过单片机的GPIO口或外部中断口来连接外部按键,以实现对系统的控制。在本实验中,我们通过连接四个按键K1-K4到单片机的P0.0口来控制两列LED的移位效果。当按键被按下时,P0.0口会读取按键状态,然后根据按键的状态来控制LED的移位方向和速度。

        具体的实现步骤如下:

        1. 初始化P0.0口,将K1-K4分别连接到不同的P0.0口上。

        2. 初始化LED状态,将两列LED的状态初始化为一开始的状态。

        3. 启动主程序,开始监听P0.0口的状态。

        4. 当K1-K4中的任意一个按键被按下时,P0.0口会读取对应的按键状态,并根据按键状态来控制LED的移位方向和速度。

        5. 在主程序中编写移位函数,实现LED的移位效果。

        6. 继续监听P0.0口的状态,等待下一个按键事件。

        通过这样的实现方式,可以实现对两列LED的控制,通过按下不同的按键来控制LED的移位方向和速度。同时,学生也可以通过调整P0.0口的配置参数来实现不同的应用场景。

硬件电路图:

五、实验步骤

        1.在Proteus中设计硬件电路,包括单片机、LED和按键。

        2. 在keil uvision中分别设计出汇编语言和C语言的源程序,包括GPIO口和LED的控制以及按键的监听和移位函数等。

        3. 将源程序下载到单片机中,并在Proteus中进行仿真测试,验证程序的正确性和稳定性。

        4. 调整程序的参数和配置,实现不同的应用场景,并进行测试验证。

        5. 整理实验报告,总结实验中的经验和教训,并提出改进建议。

六、程序代码

1.C语言代码:

#include <reg51.h> //定义特殊功能寄存器和位寄存器

#include <intrins.h> //定义本征库函数,需要使用库中循环左右移位的函数

#define uchar unsigned char

#define uint unsigned int

sbit L_UP = P1^4; //定义按键

sbit L_DOWN = P1^5;

sbit R_UP = P1^6;

sbit R_DOWN = P1^7;

void delay(uint x) //定义延时xms函数

{

uchar i;

while(x--)

{

for(i = 0; i < 120; i++);

}

}

int judge_ac() //定义判断按键是否按下函数

{

if(P1 != 0xFF) return 1; //有键按下

else return 0; //无键按下或者键已释放

}

void main()

{

P0 = 0xFE;P2 = 0xFE; //初始化P0和P2,让第一个灯亮起来

while(1)

{

if(judge_ac()) //有键按下

{

delay(20); //延时20ms消抖

if(judge_ac()) //判断是否真的有键按下

{

if(!L_UP)

    P0 = _cror_(P0,1);

else if(!L_DOWN)

P0 = _crol_(P0,1);

else if(!R_UP)

P2 = _cror_(P2,1);

else if(!R_DOWN)

P2 = _crol_(P2,1);

while(judge_ac()); //等待键释放

}

}

}

}

2.汇编语言代码:

ORG 0000H       ;程序的起始地址

LJMP MAIN         ;跳转到MAIN处执行程序

ORG 0030H         ;程序的起始地址

MAIN:

MOV P0,#0FEH   ;将P0、P2引脚设置为输出,初始值为1111 1110

MOV P2,#0FEH   

MAIN0:  

MOV P1,#0FFH   ;将P1引脚设置为输入,读取键盘输入

MOV A,P1   ;将P1引脚的值送入A中

CJNE A,#0FFH,MAIN1 ;判断P1引脚上是否有键盘输入,若有则跳转到MAIN1标签                      

AJMP MAIN3   ;如果没有键盘输入,则程序跳转到MAIN3标签,继续等待键盘输入

MAIN1:

ACALL DELAY       ;延时消抖

MOV P1,#0FFH  ;再次将P1引脚设置为输入,读取键盘输入

MOV A,P1  ;将P1引脚的值读入ACC寄存器中

CJNE A,#0FFH,M  ;如果键盘输入确实存在,则程序跳转到M标签

AJMP MAIN3      ;判断P1引脚上是否有键盘输入,若没有则跳转到MAIN3标签

M:

JNB ACC.4,LP1 ;如果第4位(从右往左数)为0,则跳转到LP1标签

JNB ACC.5,LP2 ;如果第5位(从右往左数)为0,则跳转到LP2标签

JNB ACC.6,LP3 ;如果第6位(从右往左数)为0,则跳转到LP3标签

JNB ACC.7,LP4 ;如果第7位(从右往左数)为0,则跳转到LP4标签

SJMP MAIN3 ;如果都没有满足,则回到MAIN3标签,等待键盘输入

LP1:

MOV A,P0 ;将P0引脚的值读入A中

RR A ;将A中的值向右移一位

MOV P0,A ;将A中的值写入P0

SJMP MAIN3 ;跳转到MAIN3标签,等待键盘输入

LP2:

MOV A,P0 ;将P0引脚的值读入A中

RL A ;将A中的值向左移一位

MOV P0,A ;将A中的值写入P0

SJMP MAIN3 ;跳转到MAIN3标签,等待键盘输入

LP3:MOV A,P2        ;将P2引脚的值读入A中

    RR A            ;将A中的值向右移一位

    MOV P2,A        ;将A中的值写入P2

    SJMP MAIN3      ;跳转到MAIN3标签,等待键盘输入  

LP4:MOV A,P2        ;将P2引脚的值读入A中

    RL A            ;将A中的值向左移一位

    MOV P2,A            ;将A中的值写入P2

    SJMP MAIN3          ;跳转到MAIN3标签,等待键盘输入  

MAIN3:

    MOV P1,#0FFH         ;恢复P1口的状态,1111 1111

    MOV A,P1

    CJNE A,#0FFH,MAIN3   ;确认键是否释放,若没释放,则等待键释放

    SJMP MAIN0           ;跳转到MAIN0处,重新读取P1口的状态

DELAY:  ;延时函数

    MOV R1,#10

D1: MOV R2,#50

D2: DJNZ R2,D2

DJNZ R1,D1

RET

END

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

三小只程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值