【ESP32】【micropython】I2C相关函数介绍及用esp32读取mpu6050数据
- I2C接口介绍
- micropython相关函数
- i2c类实例化
- i2c类中的函数介绍
- I2C.init(scl, sda, freq)
- I2C.scan()
- I2C.start()
- I2C.stop()
- I2C.write(buf)
- I2C.readinto(buf, nack=True)
- I2C.readfrom(addr, nbytes)
- I2C.readfrom_into(addr, buf)
- I2C.writeto(addr, buf)
- I2C.readfrom_mem(addr, memaddr, nbytes, addrsize=8)
- I2C.readfrom_mem_into(addr, memaddr, buf, addrsize=8)
- I2C.writeto_mem(addr, memaddr, buf, addrsize=8)
- 【例子】用esp32读取mpu6050数据
I2C接口介绍
micropython相关函数
i2c类实例化
I2C是设备之间的两线通信协议。在物理层它只需要两个信号线:SCL 和 SDA,分别是时钟和数据线。I2C 对象关联到总线,它可以在创建时初始化,也可以稍后初始化。
与I2C有关的类定义在machine中,我们可以通过
class machine.I2C(scl, sda, freq)
实例化一个I2C的类
其中
scl为i2c设备时钟引脚对象;sda为i2c设备数据线引脚对象;freq为SCL时钟频率(0 < freq ≤ 500000(Hz))。
i2c类中的函数介绍
I2C.init(scl, sda, freq)
函数说明:初始化i2c总线。
scl:SCL信号线的I/O口
sda:SDA信号线的I/O口
freq:SCL时钟频率
示例:
i2c.init(scl=Pin(22),sda=Pin(21))
I2C.scan()
函数说明:扫描0x08到0x77之间的I2C地址,并返回设备列表。
示例:
i2c.scan()
I2C.start()
函数说明:在总线上触发START状态(SCL为高电平时,SDA转为低电平)。
示例:
i2c.start()
I2C.stop()
函数说明:在总线上触发STOP状态 (SCL为高电平时,SDA转为高电平)。
示例:
i2c.stop()
I2C.write(buf)
函数说明:buf中的数据写入到总线,并返回写入的字节数。
buf:存储数据的缓冲区
注意:
使用write()函数时要与start函数一起使用,否则无法返回写入的字节数。
示例:
buf = b'123'
i2c.start()
i2c.write(buf)
I2C.readinto(buf, nack=True)
函数说明:从总线上读取数据并存放到buf,无返回值。
buf:存储数据的缓冲区
注意:
读取的字节数是buf的长度。在接收到最后一个字节之前,总线将发送ACK信号。在接收到最后一个字节后,如果nack为True,那么将发送一个NACK信号,否则将发送一个ACK信号。 示例:
buf=bytearray(3)
i2c.readinto(buf)
I2C.readfrom(addr, nbytes)
函数说明:从指定地址设备读取数据,返回读取对象,这个对象与I2C设备有关。
addr:i2c设备地址(可由scan函数读取出来)
nbytes:要读取数据的大小
示例:
data = i2c.readfrom(24, 8)
print(data)
运行结果:
b’\x00\x02\x00\x00\xe8\x03\xe8\x03’
I2C.readfrom_into(addr, buf)
函数说明:从指定地址设备读取buf.len()个数据到buf。
addr:i2c设备地址(可由scan函数读取出来)
buf:存储数据的缓冲区
示例:
buf = bytearray(8)
i2c.readfrom_into(24, buf)
print(buf)
运行结果:
bytearray(b’\x00\x02\x00\x00\xe8\x03\xe8\x03’)
I2C.writeto(addr, buf)
函数说明:将buf中的数据写入设备,并返回写入数据的大小。
addr:i2c设备地址(可由scan函数读取出来)
buf:存储数据的缓冲区
示例:
b = bytearray(3)
b[0] = 24
b[1] = 111
b[2] = 107
i = i2c.writeto(24,b)
I2C.readfrom_mem(addr, memaddr, nbytes, addrsize=8)
函数说明:从I2C设备的寄存器中读取并返回数据。
addr:i2c设备地址(可由scan函数读取出来)
memaddr:寄存器地址
nbytes:要读取的字节大小
addrsize:指定地址大小,默认为8位(在ESP8266上这个参数无效,地址大小总是8位)
示例:
b = i2c. readfrom_mem(24, 0x58, 3)
print(b)
运行结果:
b’\x00\x02\x01’
I2C.readfrom_mem_into(addr, memaddr, buf, addrsize=8)
函数说明:从I2C设备的寄存器中读取buf.len()个数据到buf,无返回值。
addr:i2c设备地址(可由scan函数读取出来)
memaddr:寄存器地址
buf:存储数据的缓冲区
addrsize:指定地址大小,默认为8位(在ESP8266上这个参数无效,地址大小总是8位),读取数据数量是buf的长度。
示例:
buf=bytearray(8)
i2c.readfrom_mem_into(24, 0x58, buf)
I2C.writeto_mem(addr, memaddr, buf, addrsize=8)
函数说明: 将buf 中的数据全部写入到从设备 addr 的内存 memaddr。
addr:i2c设备地址(可由scan函数读取出来)
memaddr:寄存器地址
buf:存储数据的缓冲区
addrsize:指定地址大小,默认为8位(在ESP8266上这个参数无效,地址大小总是8位),读取数据数量是buf的长度。
示例:
buf = b'123'
i2c.writeto_mem(24, 0x58, buf)
【例子】用esp32读取mpu6050数据
MPU6050.py
import utime
from machine import Pin, I2C
MPU_SELF_TESTX_REG = 0X0D
MPU_SELF_TESTY_REG = 0X0E
MPU_SELF_TESTZ_REG = 0X0F
MPU_SELF_TESTA_REG = 0X10
MPU_SAMPLE_RATE_REG = 0X19
MPU_CFG_REG = 0X1A
MPU_GYRO_CFG_REG = 0X1B
MPU_ACCEL_CFG_REG = 0X1C
MPU_MOTION_DET_REG = 0X1F
MPU_FIFO_EN_REG = 0X23
MPU_I2CMST_CTRL_REG = 0X24
MPU_I2CSLV0_ADDR_REG = 0X25
MPU_I2CSLV0_REG = 0X26
MPU_I2CSLV0_CTRL_REG = 0X27
MPU_I2CSLV1_ADDR_REG = 0X28
MPU_I2CSLV1_REG = 0X29
MPU_I2CSLV1_CTRL_REG = 0X2A
MPU_I2CSLV2_ADDR_REG = 0X2B
MPU_I2CSLV2_REG = 0X2C
MPU_I2CSLV2_CTRL_REG = 0X2D
MPU_I2CSLV3_ADDR_REG = 0X2E
MPU_I2CSLV3_REG = 0X2F
MPU_I2CSLV3_CTRL_REG = 0X30
MPU_I2CSLV4_ADDR_REG = 0X31
MPU_I2CSLV4_REG = 0X32
MPU_I2CSLV4_DO_REG = 0X33
MPU_I2CSLV4_CTRL_REG = 0X34
MPU_I2CSLV4_DI_REG = 0X35
MPU_I2CMST_STA_REG = 0X36
MPU_INTBP_CFG_REG = 0X37
MPU_INT_EN_REG = 0X38
MPU_INT_STA_REG = 0X3A
MPU_ACCEL_XOUTH_REG = 0X3B
MPU_ACCEL_XOUTL_REG = 0X3C
MPU_ACCEL_YOUTH_REG = 0X3D
MPU_ACCEL_YOUTL_REG = 0X3E
MPU_ACCEL_ZOUTH_REG = 0X3F
MPU_ACCEL_ZOUTL_REG = 0X40
MPU_TEMP_OUTH_REG = 0X41
MPU_TEMP_OUTL_REG = 0X42
MPU_GYRO_XOUTH_REG = 0X43
MPU_GYRO_XOUTL_REG = 0X44
MPU_GYRO_YOUTH_REG = 0X45
MPU_GYRO_YOUTL_REG = 0X46
MPU_GYRO_ZOUTH_REG = 0X47
MPU_GYRO_ZOUTL_REG = 0X48
MPU_I2CSLV0_DO_REG = 0X63
MPU_I2CSLV1_DO_REG = 0X64
MPU_I2CSLV2_DO_REG = 0X65
MPU_I2CSLV3_DO_REG = 0X66
MPU_I2CMST_DELAY_REG = 0X67
MPU_SIGPATH_RST_REG = 0X68
MPU_MDETECT_CTRL_REG = 0X69
MPU_USER_CTRL_REG = 0X6A
MPU_PWR_MGMT1_REG = 0X6B
MPU_PWR_MGMT2_REG = 0X6C
MPU_FIFO_CNTH_REG = 0X72
MPU_FIFO_CNTL_REG = 0X73
MPU_FIFO_RW_REG = 0X74
MPU_DEVICE_ID_REG = 0X75
MPU_ADDR = 0X68
class MPU6050:
def __init__(self, sclIO, sdaIO):
self.i2c = I2C(1, scl=Pin(sclIO), sda=Pin(sdaIO))
#初始化mpu6050
self.WriteByte(MPU_PWR_MGMT1_REG, 0x80)
utime.sleep_ms(100)
self.WriteByte(MPU_PWR_MGMT1_REG, 0x00)
self.SetGyroFsr(3) #设置陀螺仪量程
self.SetAccelFsr(0) #设置加速度量程
self.SetRate(50)
self.WriteByte(MPU_INT_EN_REG, 0x00) #关闭所有中断
self.WriteByte(MPU_USER_CTRL_REG, 0x00) #iic主模式关闭
self.WriteByte(MPU_FIFO_EN_REG, 0x00) #关闭FIFO
self.WriteByte(MPU_INTBP_CFG_REG, 0x80) #INT引脚低电平有效
#设置陀螺仪量程
def SetGyroFsr(self, fsr):
self.WriteByte(MPU_GYRO_CFG_REG, fsr<<3)
#设置加速度量程
def SetAccelFsr(self, fsr):
self.WriteByte(MPU_ACCEL_CFG_REG, fsr<<3)
def SetRate(self, rate):
if rate > 1000:
rate = 1000
if rate < 4:
rate=4
data = int(1000 / rate - 1)
self.WriteByte(MPU_SAMPLE_RATE_REG, data)
self.SetLPF(rate/2)
def SetLPF(self, lpf):
data = 0
if lpf >= 188:
data = 1
elif lpf >= 98:
data = 2
elif lpf >= 42:
data = 3
elif lpf >= 20:
data = 4
elif lpf >= 10:
data = 5
else:
data = 6
self.WriteByte(MPU_CFG_REG, data)
#获取温度
def GetTemp(self):
buf = self.ReadLen(MPU_TEMP_OUTH_REG, 2)
raw = self.bytes_toint(buf[0], buf[1])
temp = 36.53 + raw / 340
return temp
#获取陀螺仪的值
def GetGyro(self):
buf = self.ReadLen(MPU_GYRO_XOUTH_REG, 6)
gx = self.bytes_toint(buf[0], buf[1])
gy = self.bytes_toint(buf[2], buf[3])
gz = self.bytes_toint(buf[4], buf[5])
return gx, gy, gz
#获取加速度的值
def GetAccel(self):
buf = self.ReadLen(MPU_ACCEL_XOUTH_REG, 6)
ax = self.bytes_toint(buf[0], buf[1])
ay = self.bytes_toint(buf[2], buf[3])
az = self.bytes_toint(buf[4], buf[5])
return ax, ay, az
def WriteByte(self, reg, data):
self.i2c.writeto_mem(MPU_ADDR, reg, bytearray([data]))
def ReadByte(self, reg):
buf = self.i2c.readfrom_mem(MPU_ADDR, reg, 1)
return bytearray(buf)
#向reg写入多个字符buf
def WriteLen(self, reg, buf):
self.i2c.writeto_mem(MPU_ADDR, reg, bytearray([buf]))
#从reg读取len个字符
def ReadLen(self, reg, len):
buf = self.i2c.readfrom_mem(MPU_ADDR, reg, len)
return bytearray(buf)
#将byte数据额转化为short类型
def bytes_toint(self, firstbyte, secondbyte):
if not firstbyte & 0x80:
return firstbyte << 8 | secondbyte
return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)
main.py
import MPU6050
mpu = MPU6050.MPU6050(sclIO=22, sdaIO=21) #实例化MPU6050类
gx, gy, gz = mpu.GetGyro() #获取陀螺仪读数
ax, ay, az = mpu.GetAccel() #获取加速度读数
temp = mpu.GetTemp() #获取温度值
print('gx:'+str(gx))
print('gy:'+str(gy))
print('gz:'+str(gz))
print('ax:'+str(ax))
print('ay:'+str(ay))
print('az:'+str(az))
print('temp:'+str(temp))