前言
很多時候需要編寫串口代碼,但是又沒有真實串口設備來調試代碼。以及本身就是要操作2個串口的情況,可以使用“虛擬串口驅動”工具方便的調試代碼。
使用方法就是點擊添加端口,此時“COM1 <-> COM2”
是一組,即對COM1寫數據會讓COM2讀到,對COM2寫數據會讓COM1讀到,是不是很方便。
下面是“虛擬串口驅動”工具的截圖,我是在網上隨便找的一個漢化版,大家可自行百度下載吧。
示例代碼
- 串口收發都是不太好控制的,因此我下面的程序使用“\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()
}
- 運行效果
總結
有時候需要調試串口代碼,但每次接設備進行調試很麻煩,使用“虛擬串口驅動”工具不僅可以用來調試代碼,甚至可以做到單元測試里面。
畢竟驗證代碼邏輯還得用上真實設備不僅麻煩,而且難以控制,使用該工具完美解決問題。