golang无需cgo的GPIO硬件控制插件库go-rpio的使用

Golang无需cgo的GPIO硬件控制插件库go-rpio的使用

go-rpio是一个用于访问Raspberry Pi上GPIO引脚的Go语言库,它不需要任何外部C库如WiringPI或bcm2835。

安装

import "github.com/stianeikeland/go-rpio/v4"

如果你使用的是较旧的不兼容go.mod的版本,应该使用:

import "github.com/stianeikeland/go-rpio"

基本使用

初始化

// 打开/dev/mem进行GPIO访问
err := rpio.Open()
if err != nil {
    panic(err)
}

// 使用完毕后取消内存映射
defer rpio.Close()

引脚操作

// 初始化引脚(BCM编号,不是物理引脚编号)
pin := rpio.Pin(10)  // BCM 10对应物理引脚19

// 设置为输出模式
pin.Output()

// 设置引脚高电平
pin.High()

// 设置引脚低电平
pin.Low()

// 切换引脚状态(高<->低)
pin.Toggle()

// 设置为输入模式
pin.Input()

// 读取引脚状态
res := pin.Read()  // 返回rpio.High或rpio.Low

// 替代语法
pin.Mode(rpio.Output)   // 设置模式
pin.Write(rpio.High)    // 写入状态

上拉/下拉电阻

pin.PullUp()     // 启用上拉电阻
pin.PullDown()   // 启用下拉电阻
pin.PullOff()    // 禁用上拉/下拉

// 替代语法
pin.Pull(rpio.PullUp)

完整示例:LED闪烁

package main

import (
	"time"
	"github.com/stianeikeland/go-rpio/v4"
)

func main() {
	// 打开GPIO内存映射
	err := rpio.Open()
	if err != nil {
		panic(err)
	}
	defer rpio.Close()

	// 使用BCM编号18(物理引脚12)
	led := rpio.Pin(18)
	
	// 设置为输出模式
	led.Output()

	// 闪烁LED
	for i := 0; i < 10; i++ {
		led.High()              // 点亮LED
		time.Sleep(time.Second) // 等待1秒
		led.Low()               // 熄灭LED
		time.Sleep(time.Second) // 等待1秒
	}
}

SPI功能

初始化

// 开始SPI通信
rpio.SpiBegin(rpio.Spi0)

// 结束SPI通信
defer rpio.SpiEnd(rpio.Spi0)

数据传输

// 发送单个字节
rpio.SpiTransmit(0x55)

// 发送多个字节
rpio.SpiTransmit(0x01, 0x02, 0x03)

// 接收n个字节
data := rpio.SpiReceive(3) // 接收3个字节

// 全双工交换数据
buffer := []byte{0x01, 0x02, 0x03}
rpio.SpiExchange(buffer) // 同时发送和接收

SPI设置

// 设置SPI速度(Hz)
rpio.SpiSpeed(1000000) // 1MHz

// 选择芯片(CE0, CE1或CE2)
rpio.SpiChipSelect(0) // 选择CE0

// 设置芯片选择极性
rpio.SpiChipSelectPolarity(0, rpio.Low) // CE0低电平有效

// 设置SPI模式(CPOL, CPHA)
rpio.SpiMode(0, 0) // 模式0

特性

  • 支持引脚方向设置(输入/输出)
  • 支持读写(高/低电平)
  • 支持上拉/下拉电阻
  • 支持PWM(硬件支持)
  • 支持时钟功能
  • 支持边沿检测

非root用户使用

可以通过/dev/gpiomem设备在非root权限下使用大部分功能(除PWM外)。需要:

  1. 确保内核支持/dev/gpiomem
  2. 创建gpio用户组并将用户加入该组
  3. 设置适当的udev规则

PWM模式仍然需要root权限。


更多关于golang无需cgo的GPIO硬件控制插件库go-rpio的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang无需cgo的GPIO硬件控制插件库go-rpio的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-rpio: 无需CGO的GPIO硬件控制库

go-rpio 是一个纯Go语言实现的GPIO库,专门为Raspberry Pi设计,无需依赖CGO即可工作。它通过直接内存映射访问GPIO寄存器,提供了简单易用的API来控制树莓派的GPIO引脚。

安装

go get github.com/stianeikeland/go-rpio/v4

基本使用

1. 初始化

package main

import (
	"fmt"
	"time"
	"github.com/stianeikeland/go-rpio/v4"
)

func main() {
	// 打开内存映射并初始化
	err := rpio.Open()
	if err != nil {
		fmt.Println("无法打开GPIO:", err)
		return
	}
	defer rpio.Close() // 确保程序退出时关闭

	// 你的GPIO控制代码将在这里
}

2. 设置引脚模式

// 设置引脚18为输出模式
pin := rpio.Pin(18)
pin.Output()

3. 控制输出

// 设置引脚为高电平
pin.High()

// 设置引脚为低电平
pin.Low()

// 切换引脚状态
pin.Toggle()

4. 读取输入

// 设置引脚17为输入模式
inputPin := rpio.Pin(17)
inputPin.Input()

// 读取引脚状态
if inputPin.Read() == rpio.High {
	fmt.Println("引脚17为高电平")
} else {
	fmt.Println("引脚17为低电平")
}

完整示例

LED闪烁示例

package main

import (
	"time"
	"github.com/stianeikeland/go-rpio/v4"
)

func main() {
	// 初始化
	err := rpio.Open()
	if err != nil {
		panic(err)
	}
	defer rpio.Close()

	// 使用物理引脚18 (BCM GPIO24)
	pin := rpio.Pin(18)
	pin.Output() // 设置为输出模式

	// 闪烁LED 10次
	for i := 0; i < 10; i++ {
		pin.High()             // 点亮LED
		time.Sleep(time.Second) // 等待1秒
		pin.Low()              // 熄灭LED
		time.Sleep(time.Second) // 等待1秒
	}
}

按钮检测示例

package main

import (
	"fmt"
	"time"
	"github.com/stianeikeland/go-rpio/v4"
)

func main() {
	err := rpio.Open()
	if err != nil {
		panic(err)
	}
	defer rpio.Close()

	// 设置引脚17为输入模式(按钮)
	buttonPin := rpio.Pin(17)
	buttonPin.Input()
	buttonPin.PullUp() // 启用内部上拉电阻

	// 设置引脚18为输出模式(LED)
	ledPin := rpio.Pin(18)
	ledPin.Output()

	fmt.Println("按下按钮控制LED (Ctrl+C退出)")

	for {
		// 当按钮按下(低电平,因为启用了上拉)
		if buttonPin.Read() == rpio.Low {
			ledPin.High() // 点亮LED
		} else {
			ledPin.Low() // 熄灭LED
		}
		time.Sleep(50 * time.Millisecond) // 防抖延迟
	}
}

高级功能

1. PWM (脉宽调制)

pin := rpio.Pin(18)
pin.Mode(rpio.Pwm) // 设置为PWM模式
pin.Freq(64000)    // 设置频率为64kHz
pin.DutyCycle(15, 32) // 占空比15/32

2. 中断检测

pin := rpio.Pin(17)
pin.Input()
pin.Detect(rpio.FallEdge) // 检测下降沿(从高到低)

for {
	if pin.EdgeDetected() { // 检查是否检测到边缘
		fmt.Println("检测到按钮按下!")
	}
	time.Sleep(time.Millisecond * 10)
}

注意事项

  1. 需要以root权限运行程序,因为需要访问内存映射:

    sudo ./your_program
    
  2. 引脚编号使用的是BCM编号(即GPIO编号),而不是物理引脚编号。

  3. 使用完毕后务必调用rpio.Close()释放资源。

  4. 该库仅适用于Raspberry Pi,不适用于其他平台。

go-rpio提供了一种简单、高效的方式来控制树莓派的GPIO,无需复杂的CGO配置,是Go语言开发树莓派硬件项目的理想选择。

回到顶部