2833|4

1万

帖子

25

TA的资源

版主

楼主
 

LIS2MDL磁场传感器的MicroPython驱动移植 [复制链接]

 

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 中另外几个传感器不太一致,使用上也稍有区别。

 

 


此内容由EEWORLD论坛网友dcexpert原创,如需转载或用于商业用途需征得作者同意并注明出处

点赞 关注(1)
 
 

回复
举报

1万

帖子

25

TA的资源

版主

沙发
 

驱动用法:

from machine import I2C
import LIS2MDL

i2c = I2C(1)
mdl = LIS2MDL.LIS2MDL(i2c)
mdl.x()
mdl.get()

 

中断程序用法:

from machine import I2C
from pyb import Timer
import LIS2MDL

i2c = I2C(1)
mdl = LIS2MDL.LIS2MDL(i2c)

def tim_irq(t):
    print(mdl.get())

tim = Timer(1, freq = 1)
tim.callback(tim_irq)

 

 
 
 

回复

1万

帖子

25

TA的资源

版主

板凳
 

github网站上的驱动:

 

链接已隐藏,如需查看请登录或者注册

 
 
 

回复

1万

帖子

25

TA的资源

版主

4
 

目前遇到的一个问题是,LIS2MDL带有温度补偿功能,但是内部的温度传感器(TEMP_OUT_L_REG (6Eh), TEMP_OUT_H_REG (6Fh) )没有详细说明,读取的温度参数和实际温度也对应不上。

 
 
 

回复

1万

帖子

25

TA的资源

版主

5
 

更新了驱动,取消了没有用到的地址参数,增加了数据转换输出(uT)。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表