打印
[应用相关]

LIS2MDL磁场传感器的MicroPython驱动移植

[复制链接]
418|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
拓新环境|  楼主 | 2020-11-5 17:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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 中另外几个传感器不太一致,使用上也稍有区别。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

5

帖子

0

粉丝