Processing 控制 51 单片机实现电梯楼层显示
使用 Processing 控制 51 单片机实现电梯楼层显示
本项目使用 Processing 作为上位机,通过串口发送数据控制 51 单片机,实现 8x8 LED 点阵显示电梯楼层的功能。
Processing 代码
import processing.serial.*;
Serial port;
void setup() {
size(200, 500);
textSize(150);
textAlign(CENTER, CENTER);
port = new Serial(this, 'COM3', 9600); // 单片机的端口号
}
void draw() {
background(225);
String floors = 'F1 F2 F3 F4 F5 F6 F7 F8 F9';
textSize(24);
fill(255, 0, 0);
textLeading(50);
text(floors, 20, 25, 40, 450);
for (int i = 0; i < 9; i++) {
fill(100);
rect(50, i * 50, 100, 50);
}
}
void mouseClicked() {
int currentFloor = -1;
for (int i = 0; i < 9; i++) {
if (mouseX >= 50 && mouseX <= 150 && mouseY >= i * 50 && mouseY <= (i + 1) * 50) {
currentFloor = i + 1;
break;
}
}
if (currentFloor > 0) {
println(currentFloor + ' floor');
port.write(currentFloor); // 向单片机发送数据
}
}
51 单片机代码
// 8*8led显示电梯楼层
// processing发送数据
// 需要配合processing代码使用
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
// 数字0~9的编码
uchar code Table[] = {
0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, // 0
0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, // 1
0x00, 0x7E, 0x02, 0x02, 0x7E, 0x40, 0x40, 0x7E, // 2
0x00, 0x7E, 0x02, 0x02, 0x7E, 0x02, 0x02, 0x7E, // 3
0x00, 0x48, 0x48, 0x48, 0x7E, 0x08, 0x08, 0x08, // 4
0x00, 0x7E, 0x40, 0x40, 0x7E, 0x02, 0x02, 0x7E, // 5
0x00, 0x7C, 0x40, 0x40, 0x7C, 0x44, 0x44, 0x7C, // 6
0x00, 0x7C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // 7
0x00, 0x7C, 0x44, 0x44, 0x7C, 0x44, 0x44, 0x7C, // 8
0x00, 0x7E, 0x42, 0x42, 0x7E, 0x02, 0x02, 0x7E // 9
};
uchar Current_Level = 1, Dest_Level = 1; // 当前楼层和目标楼层
uint r = 0; // 控制led显示的计数器
char offset = 0; // 控制led显示的偏移量
uchar val = 0; // 从processing接收到的数据
void displayDigit(); // 显示数字
void serial() interrupt 4; // 串口中断函数
void main() {
// 串口初始化
TMOD = 0x20; // 设置计数器1为8位自动重载模式
SCON = 0x50; // 设置串口为模式1,允许接收
PCON = 0x00; // 波特率不加倍
TH1 = 0xFD; // 计数器1初值,用于波特率9600
TL1 = 0xFD;
TR1 = 1; // 启动计数器1
ES = 1; // 允许串口中断
EA = 1; // 开全局中断
while (1) {
displayDigit(); // 显示数字
}
}
void serial() interrupt 4 {
if (RI == 1) { // 如果接收到数据
val = SBUF; // 读取数据
RI = 0; // 清除接收中断标志位
if (val >= 1 && val <= 9) { // 如果数据为1~9之间的数字
Dest_Level = val; // 设置目标楼层为该数字
}
}
}
void displayDigit() {
uchar i = Current_Level * 8 + r + offset; // 计算要显示的数字在Table中的索引
P0 = ~Table[i]; // 在led上显示该数字
// 根据目标楼层调整当前楼层的值以及led的显示效果
if (Current_Level < Dest_Level) { // 电梯上升
if (++r == 8) { // 到达下一个数字
r = 0;
if (++offset == 8) { // 下一个数字超出led的显示范围,需要移动偏移量
offset = 0;
Current_Level++;
}
}
} else if (Current_Level > Dest_Level) { // 电梯下降
if (++r == 8) { // 到达下一个数字
r = 0;
if (--offset == -8) { // 下一个数字超出led的显示范围,需要移动偏移量
offset = 0;
Current_Level--;
}
}
} else { // 电梯停止
if (++r == 8) r = 0; // 到达下一个数字
}
}
电气原理图
- 将单片机的 RXD 口连接到 Processing 的 TX 口,将单片机的 TXD 口连接到 Processing 的 RX 口。
- 使用一个 8*8 的 LED 点阵来显示电梯的楼层。
- 使用一个数码管来显示当前楼层和目标楼层。
- 使用一个电机来控制电梯的上下运动。
- 可以使用按键来模拟乘客按下电梯的楼层选择按钮。
- 可以使用光电开关来检测电梯是否到达指定楼层。
注意事项
- 需要根据实际情况调整 Processing 代码中的串口号 'COM3',以及 51 单片机代码中的波特率 9600。
- 需要根据实际情况调整 51 单片机代码中的 LED 连接方式以及电机控制方式。
- 可以根据需要添加其他功能,例如显示电梯运行状态、添加报警功能等。
原文地址: https://www.cveoy.top/t/topic/k38P 著作权归作者所有。请勿转载和采集!