在51单片机上完成一个八层楼的电梯模拟项目的简单的示例代码 其要求如下 1、使用键盘阵列模拟电梯按键 S1按键代表5层 S2按键代表6层 S3按键代表7层 S4按键代表8层 S5按键代表1层 S6按键代表2层 S7按键代表3层 S8按键代表4层 S13按键代表确认 2、开发板8个LED灯自下向上排列,分别对应8个楼层 3、使用8x8LED点阵屏显示1-8八个数字; 4、蜂鸣器发出“哔”声,提示电梯到达。 电梯运行流程如下: 1、初始电梯停在1楼,对应的LED灯点亮,点阵屏显示数字1; 2、按下按键上的数字键,表示电梯运行的目标楼层,对应LED灯点亮,如:按下 3,对应3层的LED灯点亮;允许多次按键,如楼层已经按过,再按不起作用; 3、按下确定键,电梯开始以0.5秒一层的速度自下向上运行,同时对应的LED灯和点阵屏随同改变,如:运行到2层,1层LED熄灭,2层LED亮起,点阵屏显示数字2; 4、电梯一直运行到目标楼层,蜂鸣器响起,提示到达目标;如有多个目标楼层,每一个目标楼层停顿三秒后电梯继续运行直到最后一个目标,此时仅有该楼层LED点亮,电梯一次运行结束; 5、不论电梯停在何层,重复步骤2-4,电梯继续运行,注意:当目标楼层中出现小于当前楼层的,电梯都以“先上后下”原则处理,即先运行到最高目标楼层后再往下运行到最低的目标楼层方停止,完成一次运行;如仅有低于当前楼层的目标楼层,则电梯直接向下运行; 6、电梯运行过程中按键不起作用。
时间: 2023-12-03 15:05:24 浏览: 177
以下是示例代码:
```c
#include <reg52.h>
sbit beep = P2^3; // 定义蜂鸣器端口
sbit key_confirm = P3^2; // 定义确认键端口
sbit led_top = P1^0; // 定义最高层LED灯端口
sbit led_bottom = P1^7; // 定义最低层LED灯端口
unsigned char key; // 保存按键值
unsigned char target_floor; // 目标楼层
unsigned char current_floor = 1; // 当前楼层
unsigned char led_value = 0x01; // LED灯值
unsigned char dot_matrix[8] = {0x7f, 0x41, 0x5d, 0x5b, 0x79, 0x6b, 0x6f, 0x49}; // 数码管0-7的编码
// 数码管扫描函数
void display(unsigned char floor)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
P2 = i; // 先选择行
P0 = dot_matrix[floor-1]; // 再输出列
delay_ms(2); // 延时一段时间
P0 = 0xff; // 关闭所有列
}
}
// LED灯扫描函数
void led_scan(unsigned char floor)
{
switch (floor)
{
case 1: led_value = 0x01; break;
case 2: led_value = 0x03; break;
case 3: led_value = 0x07; break;
case 4: led_value = 0x0f; break;
case 5: led_value = 0x1f; break;
case 6: led_value = 0x3f; break;
case 7: led_value = 0x7f; break;
case 8: led_value = 0xff; break;
default: break;
}
P1 = led_value;
}
// 延时函数
void delay_ms(unsigned int i)
{
unsigned int j, k;
for (j = 0; j < i; j++)
for (k = 0; k < 125; k++);
}
// 按键扫描函数
unsigned char key_scan()
{
unsigned char key_value = 0xff;
unsigned char i, j;
for (i = 0; i < 4; i++)
{
P3 = ~(0x01 << i); // 依次扫描4行
j = P3 & 0x0f; // 读取4列的值
if (j != 0x0f) // 判断是否有按键按下
{
delay_ms(5); // 延时一段时间
j = P3 & 0x0f; // 再次读取4列的值
if (j != 0x0f) // 再次判断是否有按键按下
{
switch (j)
{
case 0x0e: key_value = i*4+1; break; // 按键S5
case 0x0d: key_value = i*4+2; break; // 按键S6
case 0x0b: key_value = i*4+3; break; // 按键S7
case 0x07: key_value = i*4+4; break; // 按键S8
case 0x0e: key_value = 13; break; // 按键S13
default: break;
}
}
}
}
return key_value;
}
// 检查是否有目标楼层
unsigned char has_target_floor()
{
unsigned char i;
for (i = 1; i <= 8; i++)
{
if ((target_floor & 0x01 << (i-1)) != 0)
return 1;
}
return 0;
}
// 电梯运行函数
void elevator_run()
{
if (current_floor < target_floor) // 电梯向上运行
{
while (current_floor < target_floor)
{
current_floor++;
led_scan(current_floor);
display(current_floor);
beep = 0; // 蜂鸣器响
delay_ms(100);
beep = 1; // 蜂鸣器停止响
delay_ms(400);
}
}
else if (current_floor > target_floor) // 电梯向下运行
{
while (current_floor > target_floor)
{
current_floor--;
led_scan(current_floor);
display(current_floor);
beep = 0; // 蜂鸣器响
delay_ms(100);
beep = 1; // 蜂鸣器停止响
delay_ms(400);
}
}
else // 电梯已到达目标楼层
{
beep = 0; // 蜂鸣器响
delay_ms(100);
beep = 1; // 蜂鸣器停止响
delay_ms(400);
}
target_floor &= ~(0x01 << (current_floor-1)); // 清除当前楼层的目标楼层
}
void main()
{
while (1)
{
key = key_scan(); // 扫描按键
if (key != 0xff && key != 13 && (target_floor & 0x01 << (key-1)) == 0) // 如果按键有效且目标楼层中没有该楼层
{
target_floor |= 0x01 << (key-1); // 将该楼层添加到目标楼层中
led_scan(key); // 更新LED灯状态
}
if (key_confirm == 0 && has_target_floor()) // 如果确认键按下且有目标楼层
{
while (has_target_floor()) // 重复运行直到所有目标楼层到达
{
if ((target_floor & 0xff) == 0) // 如果目标楼层中只有高层楼层
{
target_floor >>= 8; // 将目标楼层向右移8位,即向下运行
current_floor = 8; // 当前楼层设为最高层
}
else // 否则先向上运行到最高目标楼层再向下运行到最低目标楼层
{
target_floor >>= 1; // 将目标楼层向右移1位
while ((target_floor & 0x01) == 0) // 找到最高目标楼层
{
target_floor >>= 1;
current_floor++;
}
elevator_run(); // 运行到最高目标楼层
while ((target_floor & 0xff) != 0) // 找到最低目标楼层
{
target_floor >>= 1;
current_floor--;
}
}
elevator_run(); // 运行到最低目标楼层
}
}
display(current_floor); // 更新数码管显示
}
}
```
阅读全文