▌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
#============================================================