Processing上位机控制51单片机实现电梯楼层显示

本项目使用Processing作为上位机,控制51单片机模拟电梯楼层显示,通过虚拟串口与Processing相连,实现实时楼层变化效果。

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; //到达下一个数字
  }
}

51单片机代码解释

  1. 串口初始化
  • TMOD = 0x20; 设置计数器1为8位自动重载模式,用于波特率发生器。
  • SCON = 0x50; 设置串口为模式1,允许接收,并且启用了接收中断。
  • PCON = 0x00; 设置波特率不加倍。
  • TH1 = 0xFD; TL1 = 0xFD; 计数器1初值,用于波特率9600。
  • TR1 = 1; 启动计数器1。
  • ES = 1; EA = 1; 允许串口中断和全局中断。
  1. 接收中断函数 serial()
  • 如果接收到数据 (RI == 1),读取数据到 val,并清除接收中断标志位 (RI = 0)。
  • 如果接收到的数据为1~9之间的数字,设置目标楼层为该数字 (Dest_Level = val)。
  1. 显示数字函数 displayDigit()
  • 根据当前楼层、目标楼层、计数器 r 和偏移量 offset 计算要显示的数字在 Table 中的索引。
  • 在LED上显示该数字 (P0 = ~Table[i])。
  • 根据目标楼层调整当前楼层的值以及LED的显示效果,模拟电梯的上升、下降和停止状态。

运行方法

  1. 使用Keli编写51单片机代码并编译下载到Proteus仿真软件中。
  2. 使用虚拟串口配对软件将Processing和51单片机连接。
  3. 运行Processing程序,点击Processing窗口中的对应楼层,模拟电梯运行,观察51单片机在Proteus中模拟的LED显示。

注意事项

  • 确保Processing程序中设置的串口号与51单片机的串口号一致。
  • 确保Processing程序和51单片机代码的波特率一致。
  • 51单片机代码中的 Table 数组存储了数字0~9的LED显示编码,可以根据实际LED连接调整。
  • 51单片机代码中的 displayDigit() 函数实现了LED的显示控制,可以根据实际需求调整。
  • 51单片机代码中的 serial() 函数处理了串口接收数据,可以根据实际需求调整。

总结

本项目利用Processing和51单片机实现了简单的电梯楼层显示,展示了Processing与单片机的串口通信和LED控制,可以作为学习Processing、51单片机和串口通信的参考。

Processing上位机控制51单片机实现电梯楼层显示

原文地址: https://www.cveoy.top/t/topic/k4no 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录