51单片机实训4:独立按键控制LED
📅 2026/7/8 12:56:32
👁️ 阅读次数
📝 编程学习
一、实训项目与目标
实训项目:独立按键控制LED
实训目标:
- 熟悉PROTEUS软件和KEIL C软件界面。
- 熟悉在PROTEUS软件中连接单片机电路图。
- 熟悉在KEIL C软件中编写单片机控制程序。
- 学会在PROTEUS软件和KEIL C软件联调单片机控制程序。
- 掌握独立键盘的设计控制过程。
二、设备与耗材
- 设备工具:计算机一台
- 实训耗材:暂无耗材
三、实训内容及过程
1. 熟悉PROTEUS与KEIL C软件
首先,分别打开PROTEUS和KEIL C软件,熟悉其基本界面、菜单栏、工具栏和项目管理方式。
2. 在PROTEUS中绘制电路图
在PROTEUS软件中,连接独立按键控制LED的单片机电路图。典型电路包括:
- AT89C51单片机最小系统(晶振、复位电路)
- 8个独立按键(一端接地,另一端分别接P0口的8个引脚)
- 8个LED(阳极通过限流电阻接VCC,阴极分别接P1口的8个引脚)
确保电路连接正确,为后续程序仿真做好准备。
电路图示例:为增强文章直观性,可在此处插入一张PROTEUS仿真电路图的截图。图片应清晰展示以下核心元件及其连接关系:
- AT89C51单片机:位于电路图中心,连接晶振和复位电路构成最小系统。
- 独立按键:8个按键一端接地,另一端分别连接到P0口的P0.0-P0.7引脚。
- LED:8个发光二极管,阳极通过220Ω限流电阻接VCC(+5V),阴极分别连接到P1口的P1.0-P1.7引脚。
- 电阻:LED的限流电阻(通常220Ω)以及可能的上拉/下拉电阻。
通过截图可以直观展示按键与P0口、LED与P1口的对应连接关系,帮助读者快速理解硬件电路设计。
3. 在KEIL C中编写控制程序
在KEIL C软件中新建工程,选择AT89C51单片机,编写独立按键控制LED的程序。核心代码如下:
#include <reg51.h> void delay10ms() { unsigned int i, j; for(i = 0; i < 100; i++) for(j = 0; j < 120; j++); } void main() { //主函数 unsigned char x; P0 = 0xff; //P0口作为输入口,置全1(内部上拉) P1 = 0xff; //P1口作为输出口,初始全灭(高电平) x = 0; while(1) { while(x == 0) { //循环判断是否有键按下 x = P0; //读键盘状态 x = ~x; //键盘状态取反(按下为1) } delay10ms(); //延时10ms去抖动 x = P0; //再次读键盘状态 x = ~x; //键盘状态取反 if(x == 0) continue; //如果无键按下则认为是按键抖动,重新扫描键盘 switch(x) { //根据键值点亮对应的发光二极管 case 0x01: P1 = 0xfe; break; //点亮第一个发光二极管(P1.0低电平) case 0x02: P1 = 0xfd; break; //点亮第二个发光二极管(P1.1低电平) case 0x04: P1 = 0xfb; break; //点亮第三个发光二极管(P1.2低电平) case 0x08: P1 = 0xf7; break; //点亮第四个发光二极管(P1.3低电平) case 0x10: P1 = 0xef; break; //点亮第五个发光二极管(P1.4低电平) case 0x20: P1 = 0xdf; break; //点亮第六个发光二极管(P1.5低电平) case 0x40: P1 = 0xbf; break; //点亮第七个发光二极管(P1.6低电平) case 0x80: P1 = 0x7f; break; //点亮第八个发光二极管(P1.7低电平) default: break; } } }程序说明:
- P0口设置为输入,内部上拉,按键按下时对应引脚被拉低。
- 通过
~x取反,将按键按下(低电平)转换为逻辑1,便于判断。 - 使用
delay10ms()函数进行按键消抖。 - 根据读取的键值(x),控制P1口相应引脚输出低电平,点亮对应的LED。
4. 联调与观察效果
在PROTEUS软件中加载编译生成的HEX文件,启动仿真。依次按下各个独立按键,观察对应的LED是否被点亮。如未达到预期效果,需检查:
- 电路连接是否正确(按键、LED极性、限流电阻)
- 程序逻辑是否有误(端口定义、消抖处理、键值判断)
- KEIL C工程配置(单片机型号、晶振频率)
反复调试直至实现独立按键对LED的准确控制。
四、思考题
问题:如果要同时按下第一、二两个按钮来点亮D1(第一个LED),如何实现?
思路提示:修改键值判断逻辑,将case语句中的条件改为检测两个按键同时按下的组合键值(例如case 0x03:),并执行点亮D1的操作(P1 = 0xfe;)。
参考答案:要实现同时按下第一、二两个按钮(P0.0和P0.1)点亮D1(P1.0),可以在switch语句中增加一个组合键值的判断。具体实现方法如下:
// 在switch语句中增加组合键值判断 switch(x) { //根据键值点亮对应的发光二极管 case 0x01: P1 = 0xfe; break; //按下第一个按键,点亮D1 case 0x02: P1 = 0xfd; break; //按下第二个按键,点亮D2 case 0x03: P1 = 0xfe; break; //同时按下第一、二个按键,点亮D1 case 0x04: P1 = 0xfb; break; //点亮第三个发光二极管(P1.2低电平) case 0x08: P1 = 0xf7; break; //点亮第四个发光二极管(P1.3低电平) case 0x10: P1 = 0xef; break; //点亮第五个发光二极管(P1.4低电平) case 0x20: P1 = 0xdf; break; //点亮第六个发光二极管(P1.5低电平) case 0x40: P1 = 0xbf; break; //点亮第七个发光二极管(P1.6低电平) case 0x80: P1 = 0x7f; break; //点亮第八个发光二极管(P1.7低电平) default: break; }代码说明:
- 当同时按下P0.0和P0.1时,P0口读取的值为
0xFC(二进制11111100)。 - 经过
~x取反后,键值x变为0x03(二进制00000011)。 - 在
switch语句中增加case 0x03:分支,执行P1 = 0xfe;操作,使P1.0输出低电平,点亮D1。 - 也可以使用
if语句实现:if(x == 0x03) { P1 = 0xfe; }。
五、实训总结
(请在此处填写本次实训的收获、遇到的问题及解决方法、对独立按键控制LED原理的理解等。)
编程学习
技术分享
实战经验