步骤
启用i2c
参考 Go实现树莓派读取bh1750光照强度
代码
package mainimport ("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 = nilreturn 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 = startAddrstartIdx = 0endIdx = 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 = endIdxendIdx += pageSizeif 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)}// 初始化I2Ci2cBus, 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, 否则会失败。。。