簡 介: 本文給出了 MicroPython內核開發筆記:書內嵌入實驗任務 中的utime軟件用例部分內容。
關鍵詞
:軟件,MicroPython,MM32F3277,utime,time
軟件用例:
這部分書稿內容包括有:
- 基礎實驗:交互查看 time 模塊的基本功能;驅動LED 閃爍;
- 利用 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 中的主要功能包括有:
ticks_cpu 與 ticks_ms 實際上輸出數值是一樣的, ticks_us 是在 ticks_ms 的基礎上僅僅乘以 1000,也就是這實際上是一個假的 us 時間延遲,對於一些需要高精度時間延時測量會產生不利影響。
利用 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閃爍
對上面 LED 閃爍實驗中,通過測量設置不同的 time.sleep_ms 數值對應 LED 閃爍頻率,分析 time 延時時間精度。
下面是對 time 延時 n 分別取值從 1 到 25變化,輸出 LED 方波頻率數值。
▲ 對應不同time延時測量LED閃爍頻率
通過對上述數值區間利用函數 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 測量電容實驗電路
測量前,將 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=R1C1⋅ln(3.3−U13.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上的電壓波形
程序運行返回的數值為 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.3−U13.381.25=9.97μF
這個數值與電容的標稱值 10微法 很接近。
本文給出了 MicroPython內核開發筆記:書內嵌入實驗任務 中的utime軟件用例部分內容。
通過實驗可以看到,在移植軟件版本中,time 延時時間存在著系統誤差,也就是移植軟件存在著BUG,這是編程人員通常會犯的錯誤。按照現在的版本, time.sleep_ms(n) 實際延時為 1.25(n+1) ms。 建議將這部分 BUG 修改掉。
在 time.ticks_us(), ticks_cpu() 最好能夠實現內部高精度定時器。
■ 相關文獻鏈接:
● 相關圖表鏈接: