步骤
启用i2c
参考 Go实现树莓派读取bh1750光照强度
代码
package main
import (
"fmt"
"periph.io/x/conn/v3/i2c"
)
type AT24C02Device struct {
dev *i2c.Dev
}
func NewAT24C02Device(addr uint16, bus i2c.BusCloser) (*AT24C02Device, error) {
var (
dev = &AT24C02Device{}
//err error
)
dev.dev = &i2c.Dev{Addr: addr, Bus: bus}
return dev, nil
}
func (b *AT24C02Device) Init() error {
return nil
}
func (b *AT24C02Device) Destroy() error {
b.dev = nil
return nil
}
func (b *AT24C02Device) ReadAll() ([]byte, error) {
return b.read(0, 255)
}
func (b *AT24C02Device) Read(startAddr, size uint) ([]byte, error) {
return b.read(startAddr, (startAddr+size)-1)
}
func (b *AT24C02Device) read(startAddr, endAddr uint) ([]byte, error) {
var bs = []byte{byte(startAddr)}
var readBytes = make([]byte, endAddr-startAddr+1)
fmt.Println("size: ", endAddr-startAddr+1)
err := b.dev.Tx(bs, readBytes)
return readBytes, err
}
func (b *AT24C02Device) EarseAllTo(v byte) error {
var (
bs = make([]byte, 256)
)
for i := range bs {
bs[i] = v
}
return b.write(0, bs)
}
func (b *AT24C02Device) Write(startAddr uint, bs []byte) error {
return b.write(startAddr, bs)
}
func (b *AT24C02Device) write(startAddr uint, bs []byte) (err error) {
var (
//recvBytes = make([]byte, 1)
datLen = len(bs)
pageSize = 8 // 数据手册是 8byte, 树莓派可支持16字节/页
addr = startAddr
startIdx = 0
endIdx = pageSize - int(startAddr)%pageSize
)
if endIdx > datLen {
endIdx = datLen
}
for {
fmt.Println("Addr: ", addr, ", startIndex: ", startIdx, ", endIndex: ", endIdx, bs)
if err = b.writePage(addr, bs[startIdx:endIdx]); nil != err {
return
}
time.Sleep(time.Millisecond * 5)
if endIdx >= datLen {
break
}
addr += uint(pageSize)
startIdx = endIdx
endIdx += pageSize
if endIdx > datLen {
endIdx = datLen
}
}
return
}
func (b *AT24C02Device) writePage(startAddr uint, bs []byte) error {
var writeBytes = make([]byte, 1)
writeBytes[0] = byte(startAddr)
writeBytes = append(writeBytes, bs...)
_, err := b.dev.Write(writeBytes)
return err
}
测试
// 初始化硬件
if _, err := host.Init(); err != nil {
log.Fatal(err)
}
// 初始化I2C
i2cBus, err := i2creg.Open("")
if err != nil {
log.Fatalf("Failed to open I2C bus: %v", err)
}
defer i2cBus.Close()
at24c02, err := NewAT24C02Device(0x51, i2cBus)
if nil != err {
fmt.Println(err)
return
}
fmt.Println(at24c02.ReadAll())
fmt.Println(at24c02.Read(0x00, 1))
fmt.Println(at24c02.Write(0x13, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
Note
- 写起始地址,数据手册是word,stm写的时候也是uint16, 而树莓派实际写地址是byte, 对于256够用, 但超过256的存储模块还没试过, 不知道怎么样的
- 数据手册有提过, 两次写的间隔Twr时间, 5ms, 所以两次写页时延时5ms, 否则会失败。。。