概述
文章目录
- 1.概述
- 2.主要用到的软件说明
- 3.创建虚拟串口对
- 4.搭建Proteus仿真电路
- ① 电路示意框图
- ② DB9管脚定义及连接参考
- ③ 绘制电路原理图
- ④ 设置DB9串口及串口助手参数
- ⑤ 加载准备好的测试代码hex文件
- ⑥检验结果是否正确
- 5.附录:测试代码
- 6.小结
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
- VSPD(Virtual Serial Port Driver)
VSPD是一款本地虚拟串口的软件。 可以虚拟2个串口然后连接起来实现自发自收调试,让你的程序读一个串口,另外一个串口你就用来串口调试工具。在下面示例使用到的版本为VSPD v6.9,详情如下图所示:
软件下载地址:https://www.eltima.com/vspd-post-download.html
3.创建虚拟串口对
① 打开安装好的VSPD软件,设置好需要创建的串口对的端口号(这里使用COM2和COM3作为示例),然后点击【添加端口】按钮;
② 进入【Custom pinout】选项卡,红色框内的参数保持默认,如果需要设置流控和串口类型的,可以更加实际情况进行设置,这里不作叙述。
③ 测试创建的虚拟串口对是否能正常进行通信,下面以【9600波特率,8位数据位,1位停止位,无校验,无流控】进行测试,需要的波特率只需要在串口助手中修改即可,和平常的串口无异;经过测试,确定虚拟串口通信正常,结果如下图:
4.搭建Proteus仿真电路
① 电路示意框图
② DB9管脚定义及连接参考
③ 绘制电路原理图
这里的MCU使用AT89C51来做演示,这里的51单片机并没有接外围电路,因为在Proteus仿真软件里面不接也是可以正常运行的。
(注:由于MAX232在Proteus中的非符号管脚并无取反的作用,所以需要在12脚和14脚输出时添加一个非门器件)
④ 设置DB9串口及串口助手参数
这里【Component Reference】和【Component Value】不是必填选项,下面的端口选择我们之前创建的虚拟串口对【COM2和COM3】中的其中一个,演示时我这边使用【串口3,波特率9600,8位数据位,1位停止位,无校验,无流控】的参数条件。在串口助手中使用【串口2,波特率9600,8位数据位,1位停止位,无校验,无流控】。
⑤ 加载准备好的测试代码hex文件
⑥检验结果是否正确
在Proteus中点击运行仿真按钮,上电后MCU向PC的串口助手发送【I am serial port 3!rn】,然后手动发送一句【I am serial port 2!rn】,MCU回复接收到的内容,测试结果和程序一致。
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
// 定义结束符为回车符 "rn"
#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!rn");
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!rn"); // 提示缓冲区溢出
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 != '