LIS2MDL是磁场传感器,可以测试三轴方向的磁场强度。LIS2MDL使用了标准I2C接口,通过寄存器的方式读取内部的传感器数据和设置工作模式。
LIS2MDL有三种工作模式:连续模式、单次模式、待机模式。单次模式(Single mode)和其它传感器的oneshot模式类似,都是为了降低功耗而设计,在单次模式下,传感器采集数据,完成后自动转入待机模式。不过LIS2MDL没有单独的oneshot/Single mode寄存器,而是每次都需要在寄存器 CFG_REG_A 中修改 MD (模式)位。在默认情况下(上电后),传感器处于待机模式,因此需要改变传感器的工作模式才能读取磁场的数据。
虽然没有专门的oneshot寄存器,但是为了保持和其它传感器驱动用法一致,在这次移植的驱动中增加了oneshot_mode()函数,用于设置传感器工作模式。
完整的驱动程序如下:
# LIS2MDL magnetic seneor micropython drive
# ver: 1.0
# License: MIT
# Author: shaoziyang (shaoziyang@micropython.org.cn)
# v1.0 2019.7
LIS2MDL_CFG_REG_A = const(0x60)
LIS2MDL_CFG_REG_C = const(0x62)
LIS2MDL_STATUS_REG = const(0x67)
LIS2MDL_OUTX_L_REG = const(0x68)
LIS2MDL_OUTY_L_REG = const(0x6A)
LIS2MDL_OUTZ_L_REG = const(0x6C)
class LIS2MDL():
def __init__(self, i2c, addr = 0x1E):
self.i2c = i2c
self.addr = addr
self.tb = bytearray(1)
self.rb = bytearray(1)
# LP=0 ODR=0 MD=0
self.setreg(LIS2MDL_CFG_REG_A, 0x00)
# BDU=1
self.setreg(LIS2MDL_CFG_REG_C, 0x10)
self.oneshot = False
self.irq_v = [0, 0, 0]
def int16(self, d):
return d if d < 0x8000 else d - 0x10000
def setreg(self, reg, dat):
self.tb[0] = dat
self.i2c.writeto_mem(self.addr, reg, self.tb)
def getreg(self, reg):
self.i2c.readfrom_mem_into(self.addr, reg, self.rb)
return self.rb[0]
def get2reg(self, reg):
return self.getreg(reg) + self.getreg(reg+1) * 256
def oneshot_mode(self, oneshot=None):
if oneshot is None:
return self.oneshot
else:
self.get2reg(LIS2MDL_OUTX_L_REG)
self.get2reg(LIS2MDL_OUTY_L_REG)
self.get2reg(LIS2MDL_OUTZ_L_REG)
self.getreg(LIS2MDL_CFG_REG_A)
self.oneshot = oneshot
self.rb[0] &= 0xFC
if oneshot:
self.rb[0] |= 0x01
pyb.delay(5)
self.setreg(LIS2MDL_CFG_REG_A, self.rb[0])
def ONE_SHOT(self):
if self.oneshot:
self.oneshot_mode(1)
while 1:
if self.getreg(LIS2MDL_STATUS_REG) & 0x08:
return
def x(self):
self.ONE_SHOT()
return self.int16(self.get2reg(LIS2MDL_OUTX_L_REG))
def y(self):
self.ONE_SHOT()
return self.int16(self.get2reg(LIS2MDL_OUTY_L_REG))
def z(self):
self.ONE_SHOT()
return self.int16(self.get2reg(LIS2MDL_OUTZ_L_REG))
def get(self):
self.ONE_SHOT()
self.irq_v[0] = self.int16(self.get2reg(LIS2MDL_OUTX_L_REG))
self.irq_v[1] = self.int16(self.get2reg(LIS2MDL_OUTY_L_REG))
self.irq_v[2] = self.int16(self.get2reg(LIS2MDL_OUTZ_L_REG))
return self.irq_v
值得注意的是,LIS2MDL寄存器风格和 X-NUCLEO-IKS01A3 中另外几个传感器不太一致,使用上也稍有区别。
|