3750|4

1万

帖子

24

TA的资源

版主

楼主
 

LSM6DSO的MicroPython驱动移植 [复制链接]

 

每天一个X-NUCLEO-IKS01A3开发板的传感器MicroPython驱动移植,今天完成了LSM6DSO陀螺仪的驱动,也是最后一个驱动程序,下一步预备开始将这些驱动移植到MakeCode,这样以后大家也可以在MakeCode上用图形化方式使用它们了。

 

LSM6DSO可以看成是一颗芯片里面封装了两个传感器,控制的时候加速度和角速度也是分别控制的,所以LSM6DSO的体积也比其它几个传感器都要大一些(其它几个传感器都是2x2mm,LSM6DSO是2.5x3mm)。

 

从寄存器上看,LSM6DSO和LIS2DW12类似,分为控制寄存器、状态寄存器、输出寄存器、中断寄存器、事件寄存器、FIFO寄存器等。传感器的功能非常多,也很复杂,可以编写出适合不同应用的多种驱动。不过为了简化使用,并保持和其它驱动一致的风格,这次的驱动只包含了基本的参数设置、数据读取等功能,没有包含中断、事件、FIFO等,在需要时大家可以自行添加。

 

下面是LSM6DSO的部分寄存器列表,LSM6DSO的寄存器非常多,仅列表就占用了3页。不过对于基本功能,只需要用到其中一小部分寄存器。

 

LSM6DSO最基本的使用方法是先设置LSM6DSO_CTRL1_XL和LSM6DSO_CTRL2_G寄存器,将ODR从0修改为合适的数值,就可以开始读取数据了。和X-NUCLEO-IKS01A3开发板上其它传感器不同,LSM6DSO没有oneshot或者single模式,如果要降低功耗或进入休眠,需要将传感器的ODR设置为0。因为加速度和角速度是分别控制的,所以需要分别设置两个寄存器的ODR。

 

LSM6DSO的加速度传感器可以设置±2g、±4g、±8g、±16g四种量程,而角速度可以设置125、250、500、1000、2000dps五种量程,可以按需灵活选择。LSM6DSO的输出结果是16位的,传感器的灵敏度非常高,可以将它的输出和其它类似传感器比较就清楚了。

 

可能是为了做温度补偿,LSM6DSO内部同样带有一个温度传感器,使用方法和LIS2DW12是相同的。

 

另外值得注意的是,LSM6DSO也支持最新的I3C接口标准,这部分的驱动等以后有机会补上。


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

查看本帖全部内容,请登录或者注册
点赞 关注(1)
 
 

回复
举报

1万

帖子

24

TA的资源

版主

沙发
 

 完整的驱动

  • # LSM6DSO 3D accelerometer and 3D gyroscope seneor micropython drive
  • # ver: 1.0
  • # License: MIT
  • # Author: shaoziyang (shaoziyang@micropython.org.cn)
  • # v1.0 2019.7
  • LSM6DSO_CTRL1_XL = const(0x10)
  • LSM6DSO_CTRL2_G = const(0x11)
  • LSM6DSO_CTRL3_C = const(0x12)
  • LSM6DSO_CTRL6_C = const(0x15)
  • LSM6DSO_CTRL8_XL = const(0x17)
  • LSM6DSO_STATUS = const(0x1E)
  • LSM6DSO_OUT_TEMP_L = const(0x20)
  • LSM6DSO_OUTX_L_G = const(0x22)
  • LSM6DSO_OUTY_L_G = const(0x24)
  • LSM6DSO_OUTZ_L_G = const(0x26)
  • LSM6DSO_OUTX_L_A = const(0x28)
  • LSM6DSO_OUTY_L_A = const(0x2A)
  • LSM6DSO_OUTZ_L_A = const(0x2C)
  • LSM6DSO_SCALEA = ('2g', '16g', '4g', '8g')
  • LSM6DSO_SCALEG = ('250', '125', '500', '', '1000', '', '2000')
  • class LSM6DSO():
  • def __init__(self, i2c, addr = 0x6B):
  • self.i2c = i2c
  • self.addr = addr
  • self.tb = bytearray(1)
  • self.rb = bytearray(1)
  • self.oneshot = False
  • self.irq_v = [[0, 0, 0], [0, 0, 0]]
  • self._power = True
  • self._power_a = 0x10
  • self._power_g = 0x10
  • # ODR_XL=1 FS_XL=0
  • self.setreg(LSM6DSO_CTRL1_XL, 0x10)
  • # ODR_G=1 FS_125=1
  • self.setreg(LSM6DSO_CTRL2_G, 0x12)
  • # BDU=1 IF_INC=1
  • self.setreg(LSM6DSO_CTRL3_C, 0x44)
  • self.setreg(LSM6DSO_CTRL8_XL, 0)
  • # scale=2G
  • self._scale_a = 0
  • self._scale_g = 0
  • self.scale_a('2g')
  • self.scale_g('125')
  • 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 r_w_reg(self, reg, dat, mask):
  • self.getreg(reg)
  • self.rb[0] = (self.rb[0] & mask) | dat
  • self.setreg(reg, self.rb[0])
  • def ax(self):
  • return self.int16(self.get2reg(LSM6DSO_OUTX_L_A))
  • def ay(self):
  • return self.int16(self.get2reg(LSM6DSO_OUTY_L_A))
  • def az(self):
  • return self.int16(self.get2reg(LSM6DSO_OUTZ_L_A))
  • def gx(self):
  • return self.int16(self.get2reg(LSM6DSO_OUTX_L_G))
  • def gy(self):
  • return self.int16(self.get2reg(LSM6DSO_OUTY_L_G))
  • def gz(self):
  • return self.int16(self.get2reg(LSM6DSO_OUTZ_L_G))
  • def get_a(self):
  • self.irq_v[0][0] = self.ax()
  • self.irq_v[0][1] = self.ay()
  • self.irq_v[0][2] = self.az()
  • return self.irq_v[0]
  • def get_g(self):
  • self.irq_v[1][0] = self.gx()
  • self.irq_v[1][1] = self.gy()
  • self.irq_v[1][2] = self.gz()
  • return self.irq_v[1]
  • def get(self):
  • self.get_a()
  • self.get_g()
  • return self.irq_v
  • def temperature(self):
  • try:
  • return self.int16(self.get2reg(LSM6DSO_OUT_TEMP_L))/256 + 25
  • except MemoryError:
  • return self.temperature_irq()
  • def temperature_irq(self):
  • self.getreg(LSM6DSO_OUT_TEMP_L+1)
  • if self.rb[0] & 0x80: self.rb[0] -= 256
  • return self.rb[0] + 25
  • def scale_a(self, dat=None):
  • if dat is None:
  • return LSM6DSO_SCALEA[self._scale_a]
  • else:
  • if type(dat) is str:
  • if not dat in LSM6DSO_SCALEA: return
  • self._scale_a = LSM6DSO_SCALEA.index(dat)
  • else: return
  • self.r_w_reg(LSM6DSO_CTRL1_XL, self._scale_a<<2, 0xF3)
  • def scale_g(self, dat=None):
  • if (dat is None) or (dat == ''):
  • return LSM6DSO_SCALEG[self._scale_g]
  • else:
  • if type(dat) is str:
  • if not dat in LSM6DSO_SCALEG: return
  • self._scale_g = LSM6DSO_SCALEG.index(dat)
  • else: return
  • self.r_w_reg(LSM6DSO_CTRL2_G, self._scale_g<<1, 0xF1)
  • def power(self, on=None):
  • if on is None:
  • return self._power
  • else:
  • self._power = on
  • if on:
  • self.r_w_reg(LSM6DSO_CTRL1_XL, self._power_a, 0x0F)
  • self.r_w_reg(LSM6DSO_CTRL2_G, self._power_g, 0x0F)
  • else:
  • self._power_a = self.getreg(LSM6DSO_CTRL1_XL) & 0xF0
  • self._power_g = self.getreg(LSM6DSO_CTRL2_G) & 0xF0
  • self.r_w_reg(LSM6DSO_CTRL1_XL, 0, 0x0F)
  • self.r_w_reg(LSM6DSO_CTRL2_G, 0, 0x0F)

 

 
 
 

回复

1万

帖子

24

TA的资源

版主

板凳
 
 
 

回复

1万

帖子

24

TA的资源

版主

4
 

驱动在github上的网址,以后更新会同步到github上。

 

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

 

 
 
 

回复

1万

帖子

24

TA的资源

版主

5
 

驱动已经更新,保留原始数据输出同时,输出转换为实际的加速度和角速度值。

 
 
 

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

猜你喜欢
开源项目 更多>>
    随便看看
    查找数据手册?

    EEWorld Datasheet 技术支持

    相关文章 更多>>
    关闭
    站长推荐上一条 1/10 下一条
    中星联华&ADI明日直播
    直播主题:大咖面对面,轻松玩转高速ADC性能测试
    直播时间:3月25日(周二)14:00
    活动奖励:京东卡、双肩包

    查看 »

     
    EEWorld订阅号

     
    EEWorld服务号

     
    汽车开发圈

     
    机器人开发圈

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

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

    北京市海淀区中关村大街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
    快速回复 返回顶部 返回列表