• 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语言来操作要方便很多。不过这其实是麻烦的地方包的开发者都处理封装好了,去查看源码时可以看到各个平台实现串口操作时该麻烦的还是麻烦,不过我们只是拿来用不用关心这么多。

  • 相关阅读:
    树莓派基本配置(2)
    HTML期末学生大作业-使用HTML+CSS技术仿传智博客网站
    Python中使用IDLE调试程序
    文件服务之nfs
    超省流量的手机浏览器,多御安全浏览器手机版上线了
    JMeter接口测试工具基础— 取样器sampler(二)
    Gson解析会丢失默认属性值
    Python接口自动化封装导出excel方法和读写excel数据
    一个基于SpringBoot+Vue前后端分离学生宿舍管理系统详细设计实现
    SpringBoot使用spring.config.import多种方式导入配置文件
  • 原文地址:https://blog.csdn.net/Naisu_kun/article/details/139784397