51单片机接收Processing数据实现电梯楼层显示-8*8 LED仿真
51单片机接收Processing数据实现电梯楼层显示 - 8*8 LED仿真
本项目使用51单片机控制8*8 LED显示电梯当前楼层,通过Protues仿真和Keli编程,接收Processing发送的楼层数据并模拟电梯运行过程。
项目环境:
- 51单片机 (Keli编程)
- 8*8 LED 显示模块 (Protues仿真)
- Processing (上位机程序)
- 虚拟串口配对软件 (连接Processing和51单片机)
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; //到达下一个数字
}
}
代码说明:
-
Processing程序:
- 使用
processing.serial库实现串口通信。 setup()函数初始化串口并设置窗口大小和文字样式。draw()函数绘制电梯楼层按钮界面。mouseClicked()函数处理鼠标点击事件,读取点击的楼层并发送给单片机。
- 使用
-
51单片机程序:
- 定义数字0~9的编码数组
Table,用于控制8*8 LED显示。 - 初始化串口并设置中断。
serial()函数处理串口中断,读取接收到的数据并更新目标楼层。displayDigit()函数根据当前楼层和目标楼层控制LED显示,模拟电梯运行过程。
- 定义数字0~9的编码数组
程序运行步骤:
- 使用Protues仿真51单片机和8*8 LED模块,并连接虚拟串口。
- 启动Processing程序,并选择与虚拟串口对应的端口号。
- 点击Processing窗口中的楼层按钮,发送数据给51单片机。
- 51单片机接收数据后,更新目标楼层,控制LED显示模拟电梯运行。
注意事项:
- 确保Processing程序和51单片机程序使用的波特率一致。
- 调整虚拟串口设置,使Processing和51单片机能够正常通信。
- 51单片机程序中,
P0端口连接8*8 LED模块,根据具体硬件连接情况进行调整。 - 可以根据需要修改程序代码,实现更多功能,例如:
- 添加电梯门的开闭动画
- 添加电梯运行的音效
- 添加更多楼层
相关资料:
最后,希望本项目能够帮助大家更好地理解51单片机和Processing的串口通信,并提供一个有趣的编程实践。
原文地址: https://www.cveoy.top/t/topic/k4nu 著作权归作者所有。请勿转载和采集!