没有真实串口设备时使用”虚拟串口驱动”调试你的串口代码

前言

很多时候需要编写串口代码,但是又没有真实串口设备来调试代码。以及本身就是要操作2个串口的情况,可以使用“虚拟串口驱动”工具方便的调试代码。
使用方法就是点击添加端口,此时“COM1 <-> COM2”是一组,即对COM1写数据会让COM2读到,对COM2写数据会让COM1读到,是不是很方便。
下面是“虚拟串口驱动”工具的截图,我是在网上随便找的一个汉化版,大家可自行百度下载吧。

示例代码

  1. 串口收发都是不太好控制的,因此我下面的程序使用“\n”作为结束符,当收到“\n”时认为本次接收数据已完整,发送数据结尾带上“\n”。
package main

import (
    "fmt"
    "os"

    "github.com/tarm/serial"
)

/* //www.eltima.com/products/vspdxp/ : 虚拟串口工具 */
func main() {
    if len(os.Args) != 3 {
        return
    }
    com, err := serial.OpenPort(&serial.Config{
        Name:     os.Args[1],
        Baud:     9600,
        Size:     8,
        Parity:   serial.ParityNone,
        StopBits: serial.Stop1,
    })
    if err != nil {
        panic(err)
    }
    defer com.Close()

    var n int
    buf := make([]byte, 128)
    if os.Args[2] == "server" {
        for {
            n, err = readCom(com, buf)
            if err != nil {
                panic(err)
            }
            fmt.Printf("[%s]\n", buf[:n])

            err = writeCom(com)
            if err != nil {
                panic(err)
            }
        }
    } else {
        for {
            err = writeCom(com)
            if err != nil {
                panic(err)
            }

            n, err = readCom(com, buf)
            if err != nil {
                panic(err)
            }
            fmt.Printf("[%s]\n", buf[:n])
        }
    }
}

func readCom(com *serial.Port, buf []byte) (int, error) {
    cnt := 0
    for {
        n, err := com.Read(buf[cnt:])
        if err != nil {
            return 0, err
        }
        for i := cnt + n; i >= cnt; i-- {
            if buf[i] == '\n' {
                // 找到结束标记符,确定是一条完整的信息
                return i, nil
            }
        }
        cnt += n
    }
}

func writeCom(com *serial.Port) error {
    var send string
    fmt.Scanln(&send)

    var (
        buf   = []byte(send + "\n")
        end   = len(buf)
        start = 0
    )
    for start < end {
        n, err := com.Write(buf[start:])
        if err != nil {
            return err
        }
        start += n
    }
    // 确保所有数据都发送完成,然后刷新缓存
    return com.Flush()
}
  1. 运行效果

总结

有时候需要调试串口代码,但每次接设备进行调试很麻烦,使用“虚拟串口驱动”工具不仅可以用来调试代码,甚至可以做到单元测试里面。
毕竟验证代码逻辑还得用上真实设备不仅麻烦,而且难以控制,使用该工具完美解决问题。