MicroPython内核开发笔记书内软件用例 :utime 的实验用例

简 介: 本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的utime软件用例部分内容。

关键词 软件MicroPythonMM32F3277utimetime

书稿内容
目 录
Contents
基础实验
延时的精度
测量实验
总 结
修改建议

软件用例:
这部分书稿内容包括有:

  1. 基础实验:交互查看 time 模块的基本功能;驱动LED 闪烁;
  2. 利用 time 测量软件执行时间,从而测量 端口信号的时间间隔。
  • 书稿内位置:

§01 稿内容


一、基础实验

1、查看time功能

通过以下命令,可以查看 time 的基本功能。

import time

dir(time)
time.ticks_cpu()
time.ticks_ms()
time.ticks_us()

命令输出结果为:

['__name__', 'sleep', 'sleep_ms', 'sleep_us', 'ticks_add', 'ticks_cpu', 'ticks_diff', 'ticks_ms', 'ticks_us']
158519
158520
158521000
>>> 

从上面可以看到 time 中的主要功能包括有:

  • 延迟命令: sleep, sleep_ms, sleep_us
  • 时钟命令:ticks_cpu, ticks_ms, ticks_us, tikcs_diff

ticks_cpu 与 ticks_ms 实际上输出数值是一样的, ticks_us 是在 ticks_ms 的基础上仅仅乘以 1000,也就是这实际上是一个假的 us 时间延迟,对于一些需要高精度时间延时测量会产生不利影响。

2、闪烁LED

利用 time 的延迟功能,可以对主程序的循环做更加精确的控制。这在一些定时精度需要高的场合非常重要,比如使用主程序进行 PID 控制,要求控制循环周期严格保持设定的时长。所以精确延迟对于嵌入式软件开发非常中号。

下面程序利用 time 的延迟实现外部 LED 闪烁。

from machine                import Pin
import time

led = Pin("PC0", mode=Pin.OUT_PUSHPULL)

while True:
    led(1)
    time.sleep_ms(250)
    led(0)
    time.sleep_ms(250)

下图显示了 LED 闪烁的情况。

▲ 图1.1.1  time延时产生LED闪烁

▲ 图1.1.1 time延时产生LED闪烁

二、延时的精度

对上面 LED 闪烁实验中,通过测量设置不同的 time.sleep_ms 数值对应 LED 闪烁频率,分析 time 延时时间精度。

下面是对 time 延时 n 分别取值从 1 到 25变化,输出 LED 方波频率数值。
▲ 对应不同time延时测量LED闪烁频率

▲ 对应不同time延时测量LED闪烁频率

n取值 输出频率值(Hz)
1 200.009995
2 133.339996
3 100.0
4 80.0
5 66.669998
6 57.150002
7 50.0
8 44.450001
9 40.0
10 36.369999
11 33.330002
12 30.77
13 28.57
14 26.67
15 25.0
16 23.530001
17 22.219999
18 21.049999
19 20.0
20 19.049999
21 18.18
22 17.389999
23 16.67
24 16.0
25 15.39

通过对上述数值区间利用函数 1 / f = 2 a ⋅ ( n + b ) 1/f = 2a \cdot \left( {n + b} \right) 1/f=2a(n+b) 进行拟合,可以求得 a,b 大约为 1.25 和 1。因此,通过这个时间可以证明,在这个版本所实现的 time 延时中,存在着系统误差。 对于 time.sleep_ms(n) 语句,实际上延时时间为 1.25(n+1) ms。

三、测量实验

应用 time 中的 ticks_cpu 可以获得程序两段代码之间的时间延时,这个特性可以 应用在超声测量、电容充放电时间等,也可以用于测量 MicroPython 程序执行所消耗的时间,这在进行程序优化方面具有重要的意义。

很可惜,现在的这个版本只能够提供 ms 级别的时间分辨率。因此如果提高测量精度,还需要改进内部实现机制。

下面这个应用了单片机管脚可以配置成输入输出的模式,并对外部输入电压具有比较特性。应用 RC 充放电特性可以测量未知电容容量。测量电路如下所示,其中 R1 是已知电阻,实验中采用 10kΩ。 C1是待测电容。

▲ 图1.3.1 测量电容实验电路

▲ 图1.3.1 测量电容实验电路

测量前,将 PC1 配置成输出模式,将 C1 上的电压释放到 0V 左右。 然后将 PC1 设置成高阻输入状态, 3.3V 电源将通过 R1 对 C1 进行充电,当输入电压超过端口阈值电压 U 1 U_1 U1 之后, PC1 输入逻辑从 0 变成 1,利用 time 的 ticks_cpu 函数获得这个充电时间 t 1 t_1 t1 。 根据 RC 充放电规律可知 t 1 = R 1 C 1 ⋅ ln ⁡ ( 3.3 3.3 − U 1 ) t_1 = R_1 C_1 \cdot \ln \left( { { {3.3} \over {3.3 - U_1 }}} \right) t1=R1C1ln(3.3U13.3)

再根据已知 R1 的数值,便可以计算出待测 C1 的容值了。

下面是测试程序。

from machine                import Pin
import time

pinc = Pin("PC1", Pin.OUT_OPENDRAIN)
pinc(0)

def measureC():
    startc = time.ticks_cpu()
    pinc = Pin("PC1", Pin.IN_FLOATING)

    time.sleep_ms(1)
    while True:
        if pinc.value() != 0:
            endc = time.ticks_cpu()

            break

    pinc = Pin("PC1", Pin.OUT_OPENDRAIN)
    pinc(0)

    return endc - startc

while True:
    ret = measureC()
    print(ret)

    time.sleep_ms(1000)

如下是待测电容上的电压波形。 可以查看到,电压充到 1.84V,对应阈值电压 U 1 = 1.84 V U_1 = 1.84V U1=1.84V
▲ 待测C1上的电压波形

▲ 待测C1上的电压波形

程序运行返回的数值为 65。 根据前面延时精度测量可知,实际充电时间 t 1 = 65 × 1.25 = 81.25   m s t_1 = 65 \times 1.25 = 81.25\,ms t1=65×1.25=81.25ms 。根据已知 R 1 = 10 k Ω R_1 = 10k\Omega R1=10kΩ ,可以得到待测电容

C 1 = 81.25 R 1 ln ⁡ 3.3 3.3 − U 1 = 9.97 μ F C_1 = { {81.25} \over {R_1 \ln { {3.3} \over {3.3 - U_1 }}}} = 9.97\mu F C1=R1ln3.3U13.381.25=9.97μF

这个数值与电容的标称值 10微法 很接近。

  结 ※


本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的utime软件用例部分内容。


一、修改建议

1、延时系统误差

通过实验可以看到,在移植软件版本中,time 延时时间存在着系统误差,也就是移植软件存在着BUG,这是编程人员通常会犯的错误。按照现在的版本, time.sleep_ms(n) 实际延时为 1.25(n+1) ms。 建议将这部分 BUG 修改掉。

2、实现真正 us 延时

在 time.ticks_us(), ticks_cpu() 最好能够实现内部高精度定时器。


■ 相关文献链接:

● 相关图表链接:

猜你喜欢

转载自blog.csdn.net/zhuoqingjoking97298/article/details/125540999