前言

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

示例代码

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

import (
    "fmt"
    "os"

    "github.com/tarm/serial"
)

/* https://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. 运行效果
    没有真实串口设备时使用&quot;虚拟串口驱动&quot;调试你的串口代码-LMLPHP

总结

11-18 07:51