6010|4

1万

帖子

24

TA的资源

版主

楼主
 

在SensorTile上使用MicroPython(二) [复制链接]

 
本帖最后由 dcexpert 于 2017-2-9 22:00 编辑

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

LPS22HB 的 Micropython 程序移植

前面介绍了传感器的接口、主要寄存器、参数计算等方面的内容,下面就介绍用MicroPython驱动LPS22HB的方法。

为了让程序具有通用性,以及系统模块化的要求,我们将为 LPS22HB 单独建立一个 Module,这样也方便其它程序使用。python语言中,一个module和C++的子程序差不多,里面可以包含多个对象(class),每个对象提供一系列函数或方法。但是python语言没有C++那么复杂,也不是面向对象的语言,使用起来简单得多。

一个典型的mudule的结构如下,它由若干class组成,每个class下又由多个函数组成。其中比较特殊的是__init__()函数,它类似C++的构造函数初始化,在定义class变量后就会自动调用__init__()函数,默认需要进行初始化的内容都放在这个函数中。此外,class下的每个函数在定义时的默认第一个参数都是self,但是调用时并不需要使用它,self参数由python系统内部使用。更多关于python语法部分的内容,请大家参考python教程或者参考书,这里就不重复了。



对于LPS22HB传感器,我们先定义一个基本的LPS22HB类:

  1. class LPS22HB(object):
  2.     def __init__(self):
  3.         xxxx
  4.          
  5.     def func1():
  6.         xxxx
  7.          
  8.     def func2():
  9.         xxxx
  10.         
复制代码


然后再将初始化、其它功能函数逐步添加进去,最后就是一个完整的驱动了。

首先需要添加的就是初始化部分,在__init__()函数中,先添加GPIO部分,将CS的GPIO设置为输出,并设置为高电平,这样I2C才能正常工作:

  1.         # set CS high
  2.         CS_LPS22HB = Pin(LPS22HB_CS_PIN, Pin.OUT)
  3.         CS_LPS22HB(1)
  4.         CS_AG = Pin(LSM6DSM_CS_PIN, Pin.OUT)
  5.         CS_AG(1)
  6.         CS_A = Pin(LSM303AGR_CS_A_PIN, Pin.OUT)
  7.         CS_A(1)
  8.         CS_M = Pin(LSM303AGR_CS_M_PIN, Pin.OUT)
  9.         CS_M(1)
复制代码


然后再添加I2C初始化部分的代码:

  1.         # soft I2C
  2.         self.i2c = machine.I2C(-1, sda=machine.Pin('PB15'), scl=machine.Pin('PB13'))
  3.         # set open drain and pull up
  4.         sda=machine.Pin('PB15', Pin.OPEN_DRAIN, pull=Pin.PULL_UP)
  5.         scl=machine.Pin('PB13', Pin.OPEN_DRAIN, pull=Pin.PULL_UP)
复制代码



再设置LPS22HB的CTRL1_REG寄存器,让LPS22HB默认处于工作模式:


  1.         # start LPS22HB
  2.         self.setreg(0x18, LPS22HB_CTRL_REG1, LPS22HB_ADDRESS)
  3.         self.temp0 = 0
  4.         self.press = 0
  5.         self.LPS22HB_ON = True
复制代码



self.temp0、self.press、self.LPS22HB_ON是内部变量,用于后面的参数计算和状态设置。它们不是必须的,这里定义它们主要是为了方便同一模块下其它函数调用。

初始化部分完成后,就是添加其它功能函数了。大家可以发现在上面的初始化部分我们使用了一个设置寄存器的函数,因为设置和读取寄存器是一个通用性的操作,所以我们将寄存器的操作也设置成函数,这样也方便将底层和应用层分离。为了方便读取参数,我们还设置了一个读取两个相邻寄存器的函数get2reg,这个函数没有使用传感器自动递增寄存器地址的功能,是因为在传感器的BUD模式下,地址自动递增的功能是无效的,为了让程序有更好的兼容性,所以稍微牺牲了一点性能。

  1.     def setreg(self, dat, reg, addr):
  2.         buf = bytearray(2)
  3.         buf[0] = reg
  4.         buf[1] = dat
  5.         self.i2c.writeto(addr, buf)

  6.     def getreg(self, reg, addr):
  7.         buf = bytearray(1)
  8.         buf[0] = reg
  9.         self.i2c.writeto(addr, buf)
  10.         t = self.i2c.readfrom(addr, 1)
  11.         return t[0]

  12.     def get2reg(self, reg, addr):
  13.         l = self.getreg(reg, addr)
  14.         h = self.getreg(reg+1, addr)
  15.         return l+h*256
复制代码


为了增加程序的可读性和可维护下,我们将寄存器的名称定义为常量,并且将它放在class的前面,这类似于C语言中的#define。寄存器名称前面还加上LPS22HB前缀,这样可以在一个Module中存在多个芯片定义时防止和其它芯片的定义相冲突。

  1. # LPS22HB register
  2. LPS22HB_INTERRUPT_CFG= const(0x0B)
  3. LPS22HB_THS_P_L      = const(0x0C)
  4. LPS22HB_THS_P_H      = const(0x0D)
  5. LPS22HB_WHO_AM_I     = const(0x0F)
  6. LPS22HB_CTRL_REG1    = const(0x10)
  7. LPS22HB_CTRL_REG2    = const(0x11)
  8. LPS22HB_CTRL_REG3    = const(0x12)
  9. LPS22HB_FIFO_CTRL    = const(0x14)
  10. LPS22HB_REF_P_XL     = const(0x15)
  11. LPS22HB_REF_P_L      = const(0x16)
  12. LPS22HB_REF_P_H      = const(0x17)
  13. LPS22HB_RPDS_L       = const(0x18)
  14. LPS22HB_RPDS_H       = const(0x19)
  15. LPS22HB_RES_CONF     = const(0x1A)
  16. LPS22HB_INT_SOURCE   = const(0x25)
  17. LPS22HB_FIFO_STATUS  = const(0x26)
  18. LPS22HB_STATUS       = const(0x27)
  19. LPS22HB_PRESS_OUT_XL = const(0x28)
  20. LPS22HB_PRESS_OUT_L  = const(0x29)
  21. LPS22HB_PRESS_OUT_H  = const(0x2A)
  22. LPS22HB_TEMP_OUT_L   = const(0x2B)
  23. LPS22HB_TEMP_OUT_H   = const(0x2C)
  24. LPS22HB_LPFP_RES     = const(0x33)
复制代码


前面的寄存器操作、初始化等可以看成是准备工作,准备工作完成了,就是具体传感器的操作了。我们使用传感器最重要的目的就是需要获得传感器的参数,因此再定义两个函数,一个用于获取气压,一个获取温度。

  1.     def LPS22HB_temp(self):
  2.         self.temp0 = self.get2reg(LPS22HB_TEMP_OUT_L, LPS22HB_ADDRESS)
  3.         if(self.temp0 > 0x7FFF):
  4.             self.temp0 -= 65536
  5.         return self.temp0/100

  6.     def LPS22HB_press(self):
  7.         self.press = self.getreg(LPS22HB_PRESS_OUT_XL, LPS22HB_ADDRESS)
  8.         self.press += self.get2reg(LPS22HB_PRESS_OUT_L, LPS22HB_ADDRESS) * 256
  9.         return self.press/4096
复制代码


气压函数是先读取三个寄存器的参数,然后将结果除以4096,这就是按照前面介绍的计算方法进行换算的。而温度函数稍微麻烦一点,因为存在负数的问题。在python语言中不像C语言那样可以自动进行类型转换,寄存器的参数不能直接转换为负数,所以需要自己判断和转换。因为这里是一个双字节的数据,最高位就是符号位,因此如果数据大于0x7FFF或者最高位是1,那么就认为它是负数。


另外在一些情况下,需要同时读取温度和气压两个数据,所以我们可以将两个参数放到一个函数中,通过一个列表返回。这里可以直接将前面两个函数放在return的列表中。

  1.     def LPS22HB(self):
  2.         return [self.LPS22HB_temp(), self.LPS22HB_press()]
复制代码


最后,为了降低功耗,还需要让传感器可以进入掉电模式,因此我们还需要增加两个功耗管理函数:

  1.     def LPS22HB_poweron(self):
  2.         t = self.getreg(LPS22HB_CTRL_REG1, LPS22HB_ADDRESS) & 0x0F
  3.         self.setreg(t|0x10, LPS22HB_CTRL_REG1, LPS22HB_ADDRESS)
  4.         self.LPS22HB_ON = True

  5.     def LPS22HB_poweroff(self):
  6.         t = self.getreg(LPS22HB_CTRL_REG1, LPS22HB_ADDRESS) & 0x0F
  7.         self.setreg(t, LPS22HB_CTRL_REG1, LPS22HB_ADDRESS)
  8.         self.LPS22HB_ON = False
复制代码


在掉电模式下(Power down),传感器的最低功耗是1uA。其实LPS22HB的功耗也不高,在ODR和LC_EN都是1时也只有3uA。

完成上面的工作后,我们就实现了一个最基本的LPS22HB驱动。我们可以把它保存到一个LPS22HB.py文件中,然后用下面的方法使用它:

>>> from LPS22HB import LPS22HB
>>> lp=LPS22HB()
>>> lp.LPS22HB_temp()
16.17
>>> lp.LPS22HB_press()
1025.827
>>> lp.LPS22HB()
[16.14, 1025.839]


如果用dir(LPS22HB),可以查看全部的函数

>>> dir(LPS22HB)
['__qualname__', 'LPS22HB_poweron', '__module__', 'LPS22HB_press', 'LPS22HB_temp', 'LPS22HB', 'getreg', 'setreg', 'get2reg', 'LPS22HB_poweroff', '__init__']

如果想进一步完善LPS22HB驱动,增加功能,使用中断等,大家可以在此基础上进行改进。

附:
  • 完整的LPS22HB驱动, LPS22HB.zip (1.08 KB, 下载次数: 72)
  • SensorTile的MicroPython移植,包含了HEX文件和BOARD支持文件,可以自己编译



最新回复

还有这种操作  详情 回复 发表于 2017-8-31 17:14

赞赏

2

查看全部赞赏

点赞 关注(1)
 
 

回复
举报

1366

帖子

6

TA的资源

版主

沙发
 
D大赞一个,真的很厉害
个人签名

1084534438 欢迎交流  [加油,一切皆有可能]

 
 
 

回复

1239

帖子

66

TA的资源

纯净的硅(中级)

板凳
 
很给力
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

4
 
还有这种操作,6666666
 
 
 

回复

10

帖子

5

TA的资源

一粒金砂(初级)

5
 
还有这种操作
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表