使用proteus实现51单片机的串口通讯仿真

简介: 使用proteus实现51单片机的串口通讯仿真

1. 程序需求:

  • 通过上位机控制单片机的八个LED灯的开关

2. 开发中用到的软件

  • pycharm : 开发上位机
  • VSPD : 虚拟串口
  • Proteus : 仿真电路
  • keil C51 : 写51单片机程序

3. 具体步骤

  • 首先在Proteus中连接电路:


e6752b0c7e014ec5b69260feff04e5f1.png

在keil中编写单片机代码,并将生成Hex的目标文件下载到preteus的单片机内,代码如下

#include<reg51.h>
#define ON  0;
#define OFF 1;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;
sbit LED6 = P2^5;
sbit LED7 = P2^6;
sbit LED8 = P2^7;
unsigned char DATA = 0;
void delay(unsigned int a)
{
  while(a--);
}
void Usat_Init()
{
  EA = 1;       // 打开中断总开关
  ES = 1;       // 打开串口中断开关
  SCON = 0x50;  // 选择方式1
  PCON = 0x80;  // 波特率加倍
  TH1 = 0xF3;   // 芯片频率为12MHz, 设置波特率为2400, 在SMOD作用下加倍,4800
  TL1 = 0xF3;   // 重载值
  TMOD = 0x20;  // 选择计时器1,方式2
  TR1 = 1;      // 启动计时器1
}
void main(void)
{
  unsigned char num = 3;
  Usat_Init();
  //LED1 = ON;
  while(1)
  {
  }
}
void Usat_Func() interrupt 4
{
  //delay(0xfff);
  while(RI == 0);
  RI = 0;
  DATA = SBUF;
  switch (DATA)
  {
    case 0x01:
      LED1 = ~LED1;
      break;
    case 0x02:
      LED2 = ~LED2;
      break;
    case 0x03:
      LED3 = ~LED3;
      break;
    case 0x04:
      LED4 = ~LED4;
      break;
    case 0x05:
      LED5 = ~LED5;
      break;
    case 0x06:
      LED6 = ~LED6;
      break;
    case 0x07:
      LED7 = ~LED7;
      break;
    case 0x08:
      LED8 = ~LED8;
      break;
  }
}

使用pycharm开发上位机,代码如下:

import serial
from serial.tools import list_ports
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import *
class MySerial:
    def __init__(self):
        self.ser = serial.Serial()
    # 显示连接的端口
    # 建立连接
    def connect(self, port, baudrate, bytesize, stopbits, parity, timeout):
        # 如果之前打开的串口没有关闭,这里自动关闭
        if self.ser.is_open:
            self.ser.close()
        self.ser = serial.Serial(port=port, baudrate=baudrate,bytesize=bytesize, stopbits=stopbits, parity=parity, timeout=timeout)
        print("连接成功")
    # 发送数据
    def send(self, data):
        self.ser.write(data.encode())
    # 接受数据
    def rcve(self):
        pass
    def close(self):
        self.ser.close()
class Interface:
    def __init__(self):
        self.my_serial = MySerial()
        self.window = tk.Tk()
        self.window.title("LED上位机")
        self.window.geometry("400x300")
        self.port_name_var = tk.Variable()
        self.baudrate_var = tk.Variable()
        self.button_connect_var = tk.Variable()
        self.button_connect_var.set("打开串口")
        self.serial_status = "OFF"
        self.combobox_port = ttk.Combobox(self.window, textvariable=self.port_name_var)
        self.combobox_baudrate = ttk.Combobox(self.window, textvariable=self.baudrate_var)
        self.button_connect = tk.Button(self.window, textvariable=self.button_connect_var, command=self.open_close_serial)
        self.button_led1 = tk.Button(self.window, text="LED1", command=lambda: self.command(str(chr(0x01))))
        self.button_led2 = tk.Button(self.window, text="LED2", command=lambda: self.command(str(chr(0x02))))
        self.button_led3 = tk.Button(self.window, text="LED3", command=lambda: self.command(str(chr(0x03))))
        self.button_led4 = tk.Button(self.window, text="LED4", command=lambda: self.command(str(chr(0x04))))
        self.button_led5 = tk.Button(self.window, text="LED5", command=lambda: self.command(str(chr(0x05))))
        self.button_led6 = tk.Button(self.window, text="LED6", command=lambda: self.command(str(chr(0x06))))
        self.button_led7 = tk.Button(self.window, text="LED7", command=lambda: self.command(str(chr(0x07))))
        self.button_led8 = tk.Button(self.window, text="LED8", command=lambda: self.command(str(chr(0x08))))
        self.combobox_port.place(relx=1/9, rely=1/8, relwidth=2/9, relheight=1/10)
        self.combobox_baudrate.place(relx=6/9, rely=1/8, relwidth=2/9, relheight=1/10)
        self.button_connect.place(relx=3/9, rely=5/16, relwidth=3/9, relheight=1/8)
        self.button_led1.place(relx=1 / 9, rely=2 / 4, relwidth=1 / 9, relheight=1 / 8)
        self.button_led2.place(relx=3 / 9, rely=2 / 4, relwidth=1 / 9, relheight=1 / 8)
        self.button_led3.place(relx=5 / 9, rely=2 / 4, relwidth=1 / 9, relheight=1 / 8)
        self.button_led4.place(relx=7 / 9, rely=2 / 4, relwidth=1 / 9, relheight=1 / 8)
        self.button_led5.place(relx=1 / 9, rely=3 / 4, relwidth=1 / 9, relheight=1 / 8)
        self.button_led6.place(relx=3 / 9, rely=3 / 4, relwidth=1 / 9, relheight=1 / 8)
        self.button_led7.place(relx=5 / 9, rely=3 / 4, relwidth=1 / 9, relheight=1 / 8)
        self.button_led8.place(relx=7 / 9, rely=3 / 4, relwidth=1 / 9, relheight=1 / 8)
    # 显示串口列表
    def show_list(self):
        # 显示串口列表
        self.combobox_port['values'] = [x.name for x in list(list_ports.comports())]
        # 显示波特率列表
        self.combobox_baudrate['values'] = [600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200]
    def open_close_serial(self):
        var = self.button_connect_var.get()
        if var == "打开串口":
            port = self.combobox_port.get()
            baudrate = self.baudrate_var.get()
            print(port)
            if port == "":
                return
            try:
                self.my_serial.connect(port=port, baudrate=baudrate, bytesize=8, stopbits=1, parity="N", timeout=1)
                self.button_connect_var.set("关闭串口")
                self.combobox_baudrate.configure(state="disable")
                self.combobox_port.configure(state="disable")
            except:
                showerror("串口错误", "该串口被占用或不存在!")
        else:
            self.my_serial.close()
            self.button_connect_var.set("打开串口")
            self.combobox_baudrate.configure(state="enable")
            self.combobox_port.configure(state="enable")
    def command(self, data):
        self.my_serial.send(data=data)
    def run(self):
        self.show_list()
        self.window.mainloop()
if __name__ == '__main__':
    interface = Interface()
    interface.run()

打开VSPD软件,建立一对虚拟串口,我这里的串口是COM5和COM6,一端连接的单片机,另一端连接的上位机:



7b67d44ebcbc471d9be96ff73eb5d24e.png

在开始运行前,我们需要配置proteus里面外设的波特率(由你的单片机程序设定的)。


ee8a5fa51d324fcfb8d96fdd6c4bdc4b.png


d8b8f39ea78d42beb6e4547c9e129e5b.png

仿真效果如下:


b87b3174f188439183471d9d00572882.png

目录
相关文章
|
6月前
|
物联网
STC51单片机-实验开发装置仿真-物联网应用系统设计
STC51单片机-实验开发装置仿真-物联网应用系统设计
141 0
|
6月前
|
物联网
STC51单片机-控制LED闪亮的仿真-物联网应用系统设计
STC51单片机-控制LED闪亮的仿真-物联网应用系统设计
84 0
|
1月前
基于51单片机的proteus数字时钟仿真设计
基于51单片机的proteus数字时钟仿真设计
108 1
|
6月前
|
监控 物联网
STC51单片机-双机串口通讯-物联网应用系统设计
STC51单片机-双机串口通讯-物联网应用系统设计
136 0
|
传感器 数据采集 监控
资料转发分享【毕业设计】单片机和stm32设计选题,proteues仿真、程序完整资料
资料转发分享【毕业设计】单片机和stm32设计选题,proteues仿真、程序完整资料 基于单片机寻迹巡线避障智能小车系统设计 基于单片机体温心率脉搏检测仪系统设计 基于单片机温湿度光照自动窗帘系统设计 基于单片机环境监测温湿度PM2.5系统设计 基于51单片机的波形发生器(四种波形) 基于单片机SO2 NO2 PM温湿度空气质量检测仪 基于51单片机冰箱温度控制器设计
1369 1
资料转发分享【毕业设计】单片机和stm32设计选题,proteues仿真、程序完整资料
protues 51单片机仿真电路图及代码
protues 51单片机仿真电路图及代码
275 0
protues仿真51单片机驱动继电器
protues仿真51单片机驱动继电器
64 0
|
芯片
基于单片机的抢答器设计 proteus仿真资料
基于单片机的抢答器设计 proteus仿真资料
133 0
基于单片机的抢答器设计 proteus仿真资料