Golang笔记:使用serial包进行串口通讯

目的

串口是非常常用的一种电脑与设备交互的接口。这篇文章将介绍golang中相关功能的使用。

本文使用的包为 :go.bug.st/serial
https://pkg.go.dev/go.bug.st/serial
https://github.com/bugst/go-serial

另外还有一些常见的包如:tarm/serial
https://pkg.go.dev/github.com/tarm/serial
https://github.com/tarm/serial

使用入门

这个包使用很简单,按照官方说明来其实就差不多了,这里稍微做下记录。

搜索串口

搜索电脑上的串口是最基本的操作:

package main

import (
	"log"

	"go.bug.st/serial"
)

func main() {
	ports, err := serial.GetPortsList()
	if err != nil {
		log.Fatal(err)
	}
	if len(ports) == 0 {
		log.Fatal("No serial ports found!")
	}
	for _, port := range ports {
		log.Printf("Found port: %v\n", port)
	}
}

在这里插入图片描述

上面只能搜索到串口设备,如果是USB模拟的串口设备等的还可以使用别的方式在搜索的同时获取到设备的VID&PID信息:

package main

import (
	"log"

	"go.bug.st/serial/enumerator"
)

func main() {
	ports, err := enumerator.GetDetailedPortsList()
	if err != nil {
		log.Fatal(err)
	}
	if len(ports) == 0 {
		log.Fatal("No serial ports found!")
		return
	}
	for _, port := range ports {
		log.Printf("Found port: %s\n", port.Name)
		if port.IsUSB {
			log.Printf("  VID&PID: %s&%s\n", port.VID, port.PID)
			log.Printf("  SerialNumber: %s\n", port.SerialNumber)
			log.Printf("  Product: %s\n", port.Product)
		}
	}
}

在这里插入图片描述

配置与打开

有了上面的串口名后就可以打开串口,打开时可以设置一些参数,大多数时候只要改个波特率即可:

package main

import (
	"log"

	"go.bug.st/serial"
)

func main() {
	mode := &serial.Mode{
		// default is 9600_8N1
		BaudRate: 115200,
		// DataBits          int              // Size of the character (must be 5, 6, 7 or 8)
		// Parity            Parity           // Parity (see Parity type for more info)
		// StopBits          StopBits         // Stop bits (see StopBits type for more info)
		// InitialStatusBits *ModemOutputBits // Initial output modem bits status (if nil defaults to DTR=true and RTS=true)
	}
	port, err := serial.Open("COM3", mode)
	if err != nil {
		log.Fatal(err)
	}
	
	// err := port.SetMode(mode) // 模式也可以在使用过程中更改
	// if err != nil {
	// 	log.Fatal(err)
	// }
	
	// port.Close() // 关闭串口
}

读写数据

下面是串口读写操作:

package main

import (
	"log"
	"time"

	"go.bug.st/serial"
)

func main() {
	// c := make(chan os.Signal)
	// signal.Notify(c)

	mode := &serial.Mode{
		BaudRate: 115200,
	}

	port, err := serial.Open("COM3", mode)
	if err != nil {
		log.Fatal(err)
	}

	// 下面读写测试时将用来测试的串口的RX和TX引脚外部进行短接,发送什么数据就会收到什么数据

	// 启用一个协程进行读取
	go func() {
		buff := make([]byte, 8)
		for {
			n, err := port.Read(buff) // 开始读取直到至少收到一字节数据
			if err != nil {
				log.Fatal(err)
			}
			log.Printf("Received %v bytes: %X\n", n, buff[:n])
		}
	}()

	// 启用一个协程定期发送数据
	go func() {
		for {
			n, err := port.Write([]byte{0xAA, 0xBB, 0xCC, 0xDD})
			
			// port.Drain() // 等待数据发送完成
			
			if err != nil {
				log.Fatal(err)
			}
			log.Printf("Sent %v bytes\n", n)
			time.Sleep(2 * time.Second)
		}
	}()

	select {}
	// <-c
}

在这里插入图片描述
上面测试可以看到串口数据接收可能会分多次触发。

流控制

这个包的使用很简单,最主要的就是上面一些,剩下的主要还有些流控制相关的操作,这个目前来说用的很少。最常见的是有些用流控制配合晶体管实现自复位电路的应用,这种时候需要特别注意控制串口打开时流控制的设置情况。

总结

用Golang来操作串口还是比较简单的,很多时候比单纯的用C语言来操作要方便很多。不过这其实是麻烦的地方包的开发者都处理封装好了,去查看源码时可以看到各个平台实现串口操作时该麻烦的还是麻烦,不过我们只是拿来用不用关心这么多。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值