• proteus虚拟串口实现


    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 // 定义结束符为回车符 "
    "
     27 #define END_SYMBOL0 '
    '
     28 #define END_SYMBOL1    '
    '
     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!
    ");
     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!
    "); // 提示缓冲区溢出
     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 != '')
    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             // 判断是否接收到结束符(回车 "
    ")
    122             if ((recv_buf[n - 2] == END_SYMBOL0) && (recv_buf[n - 1] == END_SYMBOL1))
    123             {
    124                 buf_flag = isend;
    125                 recv_buf[n] = '';
    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! 】,然后手动发送一句【I am serial port 2! 】,MCU回复接收到的内容,测试结果和程序一致。

    4、总结

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

      注:需要电路及软件的可以在评论区留言,有更多想了解的也可以留言。

  • 相关阅读:
    异步方法单元测试
    docker常用命令备忘
    MQ消息最终一致性解决方案(转载)
    JAVA学习知识杂烩
    ASP.NET Core快速入门(第2章:配置管理)- 学习笔记(转载)
    NETCore下IConfiguration和IOptions的用法(转载)
    ASP.NET Core 之 Identity 入门(转载)
    vue+elementui+netcore混合开发
    JWT签名与验签
    使用Machin公式计算
  • 原文地址:https://www.cnblogs.com/veis/p/12406204.html
Copyright © 2020-2023  润新知