1.概述
主要介绍如何在proteus中搭建串口通讯电路,然后在PC中使用串口助手和proteus中的MCU进行通信。
2.主要使用到的软件
① Proteus
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.实现串口通信
1、创建虚拟串口对
① 打开VSPD软件,设置好需要创建的串口对的端口号,然后点击【添加端口】按钮;
② 进入【Custom pinout】选项卡,红色框内的参数保持默认,如果需要设置流控和串口类型的,可以根据实际情况进行设置,这里不作叙述。
③ 测试创建的虚拟串口对是否能正常进行通信,下面以【9600波特率,8位数据位,1位停止位,无校验,无流控】进行测试,需要的波特率只需要在串口助手中修改即可,和平常的串口无异;经过测试,确定虚拟串口通信正常,结果如下图:
2、搭建proteus仿真电路
① 电路示意框图,我们在proteus使用DB9母头和MAX232电平转换芯片相连接
② DB9管脚定义及连接参考
③ 电路原理图,这里的MCU使用AT89C51来做演示,这里的51单片机并没有接外围电路,因为在proteus仿真软件里面不接也是可以正常运行的。
(注:由于MAX232在proteus中的非符号管脚并无取反的作用,所以需要在12脚和14脚输出时添加一个非门器件)
附1:MAX232参考电路(来自MAX232N 数据手册)
附2:使用到的器件表(可以按此名称再proteus库中直接搜索对应器件)
附3:Proteus中DB9串口参数设置及串口助手参数设置
这里【Component Reference】和【Component Value】不是必填选项,下面的端口选择我们之前创建的虚拟串口对【COM2和COM3】中的其中一个,演示时我这边使用【串口3,波特率9600,8位数据位,1位停止位,无校验,无流控】的参数条件。在串口助手中使用【串口2,波特率9600,8位数据位,1位停止位,无校验,无流控】。
③ 测试代码如下
1 /** 2 * @description: 程序实现51单片机串口接收字符串,结束符为回车符,最大接收长度为64Byte, 3 * 接收完成后返回接收结果,并清空接收缓冲区。 4 * 注意:程序只适用于11.0592MHz晶振, 12T的51单片机,暂未做兼容设计。 5 * @author: veis 6 * @date: 2020-03-04 7 * @version: v1.0 8 */
9
10 #include <reg52.h>
11
12 // 类型重定义,便于移植
13 typedef unsigned char uint8_t; 14 typedef unsigned int uint16_t; 15
16 // 定义串口接收标志枚举类型
17 enum
18 { 19 isempty = 0, // 接收缓冲区为空
20 isoverflow, // 接收缓冲区溢出
21 isend // 成功接收到结束标志符
22 } buf_flag; 23
24 // 定义接收缓冲区大小
25 #define BUFFER_SIZE 64
26 // 定义结束符为回车符 "\r\n"
27 #define END_SYMBOL0 '\r'
28 #define END_SYMBOL1 '\n'
29
30 // 外部可见函数声明
31 void uart_config(void); 32 void send_char(uint8_t ch); 33 void send_string(uint8_t *str); 34
35 // 定义串口接收缓冲区
36 uint8_t recv_buf[BUFFER_SIZE] = {0}; 37
38 void main() 39 { 40 int i = 0; 41 buf_flag = isempty; 42 uart_config(); // 初始化串口
43 send_string("I am serial port 3!\r\n"); 44 while (1) 45 { 46 if (buf_flag == isend) 47 { 48 send_string(recv_buf); // 把接收到的字符串发送回去
49 i = 0; 50 while (i < BUFFER_SIZE) 51 { 52 recv_buf[i++] = 0; 53 } 54 buf_flag = isempty; 55 } 56 else if (buf_flag == isoverflow) 57 { 58 send_string("ERROR:receive buffer is overflow!\r\n"); // 提示缓冲区溢出
59 i = 0; 60 while (i < BUFFER_SIZE) 61 { 62 recv_buf[i++] = 0; 63 } 64 buf_flag = isempty; 65 } 66 } 67 } 68
69 /** 70 * 串口参数配置函数,这里配置为9600波特率,1位停止位,8位数据位,无校验 71 */
72 void uart_config(void) 73 { 74 TMOD = 0x20; 75 SCON = 0x50; 76 TH1 = 0xfd; 77 TL1 = TH1; 78 PCON = 0x00; 79 EA = 1; 80 ES = 1; 81 TR1 = 1; 82 } 83
84 /** 85 * [send_char] 86 * @param ch [待发送的字符] 87 */
88 void send_char(uint8_t ch) 89 { 90 SBUF = ch; 91 while (!TI); 92 TI = 0; 93 } 94
95 /** 96 * [send_string] 97 * @param str [待发送的字符串首元素地址] 98 */
99 void send_string(uint8_t *str) 100 { 101 while (*str != '\0') 102 { 103 SBUF = *str++; 104 while (!TI); 105 TI = 0; 106 } 107 } 108
109 /** 110 * [uart_interrupt] 111 */
112 void uart_interrupt(void) interrupt 4
113 { 114 static uint8_t n = 0; 115 if (RI) 116 { 117 RI = 0; 118 if (n < BUFFER_SIZE - 1) 119 { 120 recv_buf[n++] = SBUF; 121 // 判断是否接收到结束符(回车 "\r\n")
122 if ((recv_buf[n - 2] == END_SYMBOL0) && (recv_buf[n - 1] == END_SYMBOL1)) 123 { 124 buf_flag = isend; 125 recv_buf[n] = '\0'; 126 n = 0; 127 } 128 } 129 else
130 { 131 n = 0; 132 buf_flag = isoverflow; 133 } 134 } 135
136 }
④ 加载通过keil生成好的hex文件(这里不介绍如何生成hex文件)
⑤ 在proteus中点击运行仿真按钮,上电后MCU向PC的串口助手发送【I am serial port 3!\r\n】,然后手动发送一句【I am serial port 2!\r\n】,MCU回复接收到的内容,测试结果和程序一致。
4、总结
整体电路并不复杂,值得注意的是proteus中MAX232电平转换芯片的管脚非属性并无效,需要自行增加非门进行设计电路仿真,注意实际设计时候并不需要非门。另外需要注意的是proteus中的DB9接口的连接方式,需要RXD接MAX232的RXD,TXD接MAX232的TXD。
注:需要电路及软件的可以在评论区留言,有更多想了解的也可以留言。