利用pyBoard的实验来讨论部分MicroPython特性

   日期:2021-03-22     浏览:106    评论:0    
核心提示: ▌01 pyBoard系统函数pyBoard 提供了pyb.micros() 返回MCU从reset开始之后度过的时间,单位us。 相类似的还有millis()。使用elapsed_micros(start), elapsed_millis(start) 可以得到 时间流逝的长度。使用这个函数可以用于程序控制以及测量函数执行时间。1.延时函数(1)测试time.sleep_us()a.测量代码ddim = []for i in range(100): start = py

 

01 pyBoard系统函数

pyBoard 提供了pyb.micros() 返回MCU从reset开始之后度过的时间,单位us。 相类似的还有millis()。使用elapsed_micros(start), elapsed_millis(start) 可以得到 时间流逝的长度。使用这个函数可以用于程序控制以及测量函数执行时间。

1.延时函数

(1)测试time.sleep_us()

a.测量代码
ddim = []
for i in range(100):
    start = pyb.micros()
    time.sleep_us(i)
    delayus = pyb.elapsed_micros(start)
    ddim.append(delayus)
b.测量结果

从测量结果来看,使用time.sleep_us所产生的延时有一个较为恒定的常量20us左右。延时的精度还是非常可靠的。

▲ delay_us测量曲线

(2)测量time.sleep_ms()

a.测量一百次 time.delay_ms(1)

下面显示了测量100次delay_ms(1)对应的数值,可以看到实际上的delay_ms()比起1ms实际上要端,而且还大约30usd的误差和突变。

▲ 测量结果time.delay_ms(1)

b.测量delay_ms(i)

测量delay_ms的逐步增长的延时。可以看到它在ms的级别对应的延迟的精度还是非常高的。

▲ 测量 time.delay_ms(i);i=1,..100

(3)测量pyb.delay

对应pyb.delay的功能与time.sleep_ms()功能相近。

▲ pyb.delay()的延时测量

2.随机数

使用pyb.rng()可以使用MCU的硬件产生随机数。

▲ 第一次运行所产生的随机数

▲ 第二次运行所产生的随机数

3. DAC; ADC

from pyb                    import ADC,DAC,LED,Pin
dac = DAC(Pin('X5'))
adc = ADC(Pin('X1'))
adcdim = []
for i in range(256):
    dac.write(i)
    val = adc.read()
    adcdim.append(val)
print(adcdim)

▲ 测量不同的DAC与ADC之间的关系

 

02 MicroPython语法

自制pyBoard的I2C实验,应用MicroPython 中给出了一些新的MicroPython的语法。下面进行总结。

1. const

应用于MicroPython定义常量变量,可以用于编译器的优化。根据测试,可以看到const必须是integer。所以下面声明中,PI是错误的の。

  • micropython.const(expr)
from micropython            import const
PI = const(3.1415)                  # Wrong: constant must be an integer
A =  const(1)
print(type(PI))
print(type(A))

对应常量幅值会出现错误。下面代码中在A=2时,会出现Exception。

from micropython            import const
A =  const(1)
B = 3
A = 2
B = 4

2.framebuf

framebuf用于给液晶显示屏给出一些内存缓存。参见: framebuf — frame buffer manipulation — MicroPython 1.14 documentation

使用frame.buffer访问framebuf对应的字节。

3.定义元组

下面代码显示了在定义元组,列表的过程中,可以使用条件幅值过程。

b = 1
a = (0, 1 if b > 0 else 2,100)
print(a)

执行结果: (0, 1, 100)

4.定义类

在定义类的时候,在基类中甚至可以运行将来在派生类中才存在的函数。比如在下面的代码中,基类中使用到了self.showA() 函数,而这个函数实际上在它的派生类 classA中才定义。相比与C++中的OO编程,它则需要在基类中定义虚拟函数,以便可以被未来的派生类所重载。

class basetype():
    def __init__(self, value):
        self.value = value
    def show(self, ):
        print(self.value)
        self.showA()
    def getvalue(self, ):
        return self.value
        
class classA(basetype):
    def __init__(self, v):
        super().__init__(v)
    def show(self, b):
        super().show()
        print(b)
    def showA(self, ):
        print('Hello:%d'%super().getvalue())
        
a = classA(3)
a.show(4)

上面代码运行结果:

3
Hello:3
4

 

▌附录

1.OLED SSD1306代码

(1)主程序代码

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTOLED.PY -- by Dr. ZhuoQing 2021-03-20
#
# Note:
#============================================================

#------------------------------------------------------------

''' 实验名称:OLED显示屏(I2C总线) 版本:v1.0 日期:2019.4 作者:01Studio '''

from machine import I2C,Pin         #从machine模块导入I2C、Pin子模块
import SSD1306

i2c = I2C(sda=Pin("Y10"), scl=Pin("Y9"))    #pyBoard I2C初始化:sda--> Y8, scl --> Y6
oled = SSD1306.SSD1306_I2C(128, 64, i2c, addr=0x3c) #OLED显示屏初始化:128*64分辨率,OLED的I2C地址是0x3c

oled.text("Hello World!", 0,  0)      #写入第1行内容
oled.text("MicroPython",  0, 20)      #写入第2行内容
oled.text("By 01Studio",  0, 50)      #写入第3行内容

oled.show()   #OLED执行显示

#------------------------------------------------------------
# END OF FILE : TESTOLED.PY
#============================================================

(2)底层代码

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# SSD1306.PY -- by Dr. ZhuoQing 2021-03-20
#
# Note:
#============================================================

# MicroPython SSD1306 OLED driver, I2C and SPI interfaces

from micropython import const
import framebuf

# register definitions
SET_CONTRAST        = const(0x81)
SET_ENTIRE_ON       = const(0xa4)
SET_NORM_INV        = const(0xa6)
SET_DISP            = const(0xae)
SET_MEM_ADDR        = const(0x20)
SET_COL_ADDR        = const(0x21)
SET_PAGE_ADDR       = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP       = const(0xa0)
SET_MUX_RATIO       = const(0xa8)
SET_COM_OUT_DIR     = const(0xc0)
SET_DISP_OFFSET     = const(0xd3)
SET_COM_PIN_CFG     = const(0xda)
SET_DISP_CLK_DIV    = const(0xd5)
SET_PRECHARGE       = const(0xd9)
SET_VCOM_DESEL      = const(0xdb)
SET_CHARGE_PUMP     = const(0x8d)

# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
    def __init__(self, width, height, external_vcc):
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
        self.init_display()

    def init_display(self):
        for cmd in (
            SET_DISP | 0x00, # off
            # address setting
            SET_MEM_ADDR, 0x00, # horizontal
            # resolution and layout
            SET_DISP_START_LINE | 0x00,
            SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
            SET_MUX_RATIO, self.height - 1,
            SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
            SET_DISP_OFFSET, 0x00,
            SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
            # timing and driving scheme
            SET_DISP_CLK_DIV, 0x80,
            SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
            SET_VCOM_DESEL, 0x30, # 0.83*Vcc
            # display
            SET_CONTRAST, 0xff, # maximum
            SET_ENTIRE_ON, # output follows RAM contents
            SET_NORM_INV, # not inverted
            # charge pump
            SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
            SET_DISP | 0x01): # on
            self.write_cmd(cmd)
        self.fill(0)
        self.show()

    def poweroff(self):
        self.write_cmd(SET_DISP | 0x00)

    def poweron(self):
        self.write_cmd(SET_DISP | 0x01)

    def contrast(self, contrast):
        self.write_cmd(SET_CONTRAST)
        self.write_cmd(contrast)

    def invert(self, invert):
        self.write_cmd(SET_NORM_INV | (invert & 1))

    def show(self):
        x0 = 0
        x1 = self.width - 1
        if self.width == 64:
            # displays with width of 64 pixels are shifted by 32
            x0 += 32
            x1 += 32
        self.write_cmd(SET_COL_ADDR)
        self.write_cmd(x0)
        self.write_cmd(x1)
        self.write_cmd(SET_PAGE_ADDR)
        self.write_cmd(0)
        self.write_cmd(self.pages - 1)
        self.write_data(self.buffer)

class SSD1306_I2C(SSD1306):
    def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
        self.i2c = i2c
        self.addr = addr
        self.temp = bytearray(2)
        super().__init__(width, height, external_vcc)

    def write_cmd(self, cmd):
        self.temp[0] = 0x80 # Co=1, D/C#=0
        self.temp[1] = cmd
        self.i2c.writeto(self.addr, self.temp)

    def write_data(self, buf):
        self.temp[0] = self.addr << 1
        self.temp[1] = 0x40 # Co=0, D/C#=1
        self.i2c.start()
        self.i2c.write(self.temp)
        self.i2c.write(buf)
        self.i2c.stop()

class SSD1306_SPI(SSD1306):
    def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
        self.rate = 10 * 1024 * 1024
        dc.init(dc.OUT, value=0)
        res.init(res.OUT, value=0)
        cs.init(cs.OUT, value=1)
        self.spi = spi
        self.dc = dc
        self.res = res
        self.cs = cs
        import time
        self.res(1)
        time.sleep_ms(1)
        self.res(0)
        time.sleep_ms(10)
        self.res(1)
        super().__init__(width, height, external_vcc)

    def write_cmd(self, cmd):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([cmd]))
        self.cs(1)

    def write_data(self, buf):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.dc(1)
        self.cs(0)
        self.spi.write(buf)
        self.cs(1)

#------------------------------------------------------------
# END OF FILE : SSD1306.PY
#============================================================

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服