proteus虚拟串口实现

1.概述

主要介绍如何在Proteus中搭建串口通讯电路,利用VSPD软件虚拟一对串口,然后在PC中使用串口助手和Proteus中的MCU进行通信。

2.主要用到的软件说明

  • Proteus EDA仿真软件

Proteus是由Lab Center Electronics公司推出的电子设计自动化(EDA)软件。除具有其它EDA软件的仿真功能,还能仿真单片机及其外围器件。在下面示例中我使用的版本为Proteus 7.8 sp2,详情如下图所示:
软件下载地址:https://www.pcsoft.com.cn/soft/27539.html

image

  • VSPD(Virtual Serial Port Driver)

VSPD是一款本地虚拟串口的软件。 可以虚拟2个串口然后连接起来实现自发自收调试,让你的程序读一个串口,另外一个串口你就用来串口调试工具。在下面示例使用到的版本为VSPD v6.9,详情如下图所示:
软件下载地址:https://www.eltima.com/vspd-post-download.html

img

3.创建虚拟串口对

① 打开安装好的VSPD软件,设置好需要创建的串口对的端口号(这里使用COM2和COM3作为示例),然后点击【添加端口】按钮;

img

② 进入【Custom pinout】选项卡,红色框内的参数保持默认,如果需要设置流控和串口类型的,可以更加实际情况进行设置,这里不作叙述。

img

③ 测试创建的虚拟串口对是否能正常进行通信,下面以【9600波特率,8位数据位,1位停止位,无校验,无流控】进行测试,需要的波特率只需要在串口助手中修改即可,和平常的串口无异;经过测试,确定虚拟串口通信正常,结果如下图:

img

4.搭建Proteus仿真电路

① 电路示意框图

img

② DB9管脚定义及连接参考

img

③ 绘制电路原理图

这里的MCU使用AT89C51来做演示,这里的51单片机并没有接外围电路,因为在Proteus仿真软件里面不接也是可以正常运行的。
(注:由于MAX232在Proteus中的非符号管脚并无取反的作用,所以需要在12脚和14脚输出时添加一个非门器件)

img

④ 设置DB9串口及串口助手参数

这里【Component Reference】和【Component Value】不是必填选项,下面的端口选择我们之前创建的虚拟串口对【COM2和COM3】中的其中一个,演示时我这边使用【串口3,波特率9600,8位数据位,1位停止位,无校验,无流控】的参数条件。在串口助手中使用【串口2,波特率9600,8位数据位,1位停止位,无校验,无流控】。

img
img

⑤ 加载准备好的测试代码hex文件

img

⑥检验结果是否正确

在Proteus中点击运行仿真按钮,上电后MCU向PC的串口助手发送【I am serial port 3!\r\n】,然后手动发送一句【I am serial port 2!\r\n】,MCU回复接收到的内容,测试结果和程序一致。

img

5.附录:测试代码

/**
 * @description: 程序实现51单片机串口接收字符串,结束符为回车符,最大接收长度为64Byte,
 *      接收完成后返回接收结果,并清空接收缓冲区。
 *     注意:程序只适用于11.0592MHz晶振, 12T的51单片机,暂未做兼容设计。
 * @author:      veis
 * @date:        2020-03-04
 * @version:  v1.0
 */
 #include <reg52.h>
 
// 类型重定义,便于移植
typedef unsigned char uint8_t;
typedef unsigned int uint16_t;

// 定义串口接收标志枚举类型
enum
{
 isempty = 0, // 接收缓冲区为空
 isoverflow, // 接收缓冲区溢出
 isend // 成功接收到结束标志符
} buf_flag; 
// 定义接收缓冲区大小
#define BUFFER_SIZE 64
// 定义结束符为回车符 "\r\n"
#define END_SYMBOL0 '\r'
#define END_SYMBOL1 '\n'

// 外部可见函数声明
void uart_config(void);
void send_char(uint8_t ch);
void send_string(uint8_t *str); 

// 定义串口接收缓冲区
uint8_t recv_buf[BUFFER_SIZE] = {0};

void main()
{
	 int i = 0;
	 buf_flag = isempty;
	 uart_config(); // 初始化串口
	 send_string("I am serial port 3!\r\n");
	 while (1)
	 {
		  if (buf_flag == isend)
		  {
		      send_string(recv_buf); // 把接收到的字符串发送回去
			  i = 0;
			  while (i < BUFFER_SIZE)
			  {
		   	  		recv_buf[i++] = 0;
			  }
			  buf_flag = isempty;
		 }
		 else if (buf_flag == isoverflow)
		 {
			send_string("ERROR:receive buffer is overflow!\r\n"); // 提示缓冲区溢出
			i = 0;
			while (i < BUFFER_SIZE)
			{
				recv_buf[i++] = 0;
			}
	  		buf_flag = isempty;
		}
	}
}

/**
 * 串口参数配置函数,这里配置为9600波特率,1位停止位,8位数据位,无校验
 */
void uart_config(void)
{
	 TMOD = 0x20;
	 SCON = 0x50;
	 TH1 = 0xfd;
	 TL1 = TH1;
	 PCON = 0x00;
	 EA = 1;
	 ES = 1;
	 TR1 = 1;
}
/**
 * [send_char]
 * @param ch [待发送的字符]
 */
void send_char(uint8_t ch)
{
	 SBUF = ch;
	 while (!TI);
	 TI = 0;
}
/**
 * [send_string]
 * @param str [待发送的字符串首元素地址]
 */
void send_string(uint8_t *str)
{
	 while (*str != '\0')
	 {
		  SBUF = *str++;
		  while (!TI);
		  TI = 0;
	 }
}
/**
 * [uart_interrupt]
 */
void uart_interrupt(void) interrupt 4
{
	 static uint8_t n = 0;
	 if (RI)
	 {
		  RI = 0;
		  if (n < BUFFER_SIZE - 1)
		  {
			   	recv_buf[n++] = SBUF;
			   	// 判断是否接收到结束符(回车 "\r\n")
			   	if ((recv_buf[n - 2] == END_SYMBOL0) && (recv_buf[n - 1] == END_SYMBOL1))
			   	{
			    		buf_flag = isend;
			    		recv_buf[n] = '\0';
			    		n = 0;
			   	}
		  }
		  else
		  {
			   	n = 0;
			   	buf_flag = isoverflow;
		  }
	}
}

6.小结

整体电路并不复杂,值得注意的是Proteus中MAX232电平转换芯片的管脚非属性并无效,需要自行增加非门进行设计电路仿真,注意实际设计时候并不需要非门。另外需要注意的是Proteus中的DB9为母头接口,而电脑PC的为公头接口,所以连接方式,需要RXD接MAX232的RXD,TXD接MAX232的TXD。

注:有什么错漏的,欢迎讨论指出,共同进步,感谢!

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页