隨著micropython 1.9.4版本的發(fā)布,micropython開(kāi)始正式支持STM32H7微控制器。STM32H7作為目前STM32 Cotex-M系列控制器中性能最高的系列,micropython在它上面的表現(xiàn)如何呢?和其它型號(hào)相比,有什么優(yōu)勢(shì)?下面我們就在NUCELO_H743開(kāi)發(fā)板上,看看MicroPython的表現(xiàn)。
從 1.9.4版開(kāi)始,micropython在支持的開(kāi)發(fā)板中增加了Nucleo-H743ZI開(kāi)發(fā)板,不過(guò)官網(wǎng)上并沒(méi)有提供開(kāi)發(fā)板的二進(jìn)制固件文件,要運(yùn)行micropython就需要自己編譯源碼。如果安裝過(guò)micropyhon編譯環(huán)境,那么只要在micropython目錄下,輸入下面命令進(jìn)行編譯:
make -C ports/stm32 BOARD=NUCLEO_H743ZI
如果沒(méi)有安裝編譯環(huán)境,可以參考另外一篇文章《在win10的ubuntu子系統(tǒng)下編譯micropython》,按照文中的方法就可以安裝編譯環(huán)境。這個(gè)方法也可以用于其它虛擬機(jī),或者ubuntu系統(tǒng)。
?
如果覺(jué)得安裝編譯環(huán)境太麻煩,或者網(wǎng)速太慢安裝不了,可以直接下載我編譯好的固件,將固件通過(guò)板載的STLink下載到芯片,就可以運(yùn)行了。
在使用前,我們需要準(zhǔn)備兩根microUSB數(shù)據(jù)線(安卓手機(jī)的數(shù)據(jù)線),以及串口終端軟件,如putty、kitty、MobaXterm等。注意不能使用串口助手之類的軟件,因?yàn)樗鼈儾恢С纸K端模式。
為什么需要兩個(gè)數(shù)據(jù)線呢?因?yàn)镾T-Link需要使用一個(gè)數(shù)據(jù)線,而開(kāi)發(fā)板上的STM32H743的USB可以接入另外一個(gè)USB。寫入固件后,先斷電一次,然后連接ST-Link,再連接另外一邊的用戶USB。如果一切操作步驟正常,這時(shí)就會(huì)顯示一個(gè)pybflash磁盤,我們可以往這個(gè)磁盤中寫入文件,運(yùn)行編寫好的程序。默認(rèn)情況下,會(huì)從main.py文件開(kāi)始運(yùn)行,所以我們可以將編寫的程序放入main.py,讓它自動(dòng)運(yùn)行。
如果是win10或者macos、Linux系統(tǒng),無(wú)需安裝任何驅(qū)動(dòng),如果是win7系統(tǒng),還需要安裝一個(gè)串口驅(qū)動(dòng),驅(qū)動(dòng)程序就在這個(gè)PYBFLASH磁盤中。安裝后,我們可以看到有兩個(gè)串口,一個(gè)是ST-Link的串口,另外一個(gè)就是MicroPython的串口了。
運(yùn)行一個(gè)終端軟件,串口可以設(shè)置為上面兩個(gè)串口中的任何一個(gè),并設(shè)置波特率是115200,流量控制選擇None。下面以kitty軟件為例,其它軟件的使用也是類似的:
設(shè)置好參數(shù)后,點(diǎn)open?按鈕,就可以打開(kāi)終端了。按下回車鍵,如果出現(xiàn)>>>提示,就代表運(yùn)行成功了。這時(shí)按下ctrl-B鍵,就可以看到版本提示。
按照習(xí)慣,我們先從點(diǎn)燈開(kāi)始。在MicroPython中,默認(rèn)定義了LED類型,我們可以通過(guò)pyb.LED進(jìn)行控制,如:
pyb.LED(1).on()pyb.LED(1).off()
因?yàn)镹UCLEO_H743開(kāi)發(fā)板上有3個(gè)LED,所以我們也可以使用它們做一個(gè)跑馬燈:
while 1: for i in range(1, 4): pyb.LED(i).toggle() pyb.delay(500) pyb.LED(i).toggle() pyb.delay(500)
按鍵的使用也非常容易,MicroPython中有一個(gè)內(nèi)置的Switch類,可以用來(lái)讀取按鍵。下面的程序通過(guò)按鍵來(lái)控制LED1的狀態(tài):
sw=pyb.Switch()sw()while 1: if sw(): pyb.LED(1).on() else: pyb.LED(1).off()
定時(shí)器也是我們?cè)?a target="_blank">編程時(shí)最常用的功能之一,下面的程序中,分別在定時(shí)器6和定時(shí)器7的回調(diào)函數(shù)中控制LED1和LED3,并使用不同的頻率閃爍。
tm = pyb.Timer(6, freq=2)tm.callback(lambda t: pyb.LED(1).toggle())tm2 = pyb.Timer(7, freq=5)tm2.callback(lambda t: pyb.LED(3).toggle())雖然STM32H743有22個(gè)定時(shí)器,但是micropython目前只支持到定時(shí)器14,超過(guò)14的定時(shí)器可以定義,但是一旦使用就會(huì)死機(jī)。
PWM也是很常用的功能,它是通過(guò)定時(shí)器控制GPIO實(shí)現(xiàn)的,是定時(shí)器的一種特殊工作模式。下面是在MicroPython中使用PWM的方法,下面程序通過(guò)定時(shí)器3的CH3控制LED1(PB0),通過(guò)周期改變占空比實(shí)現(xiàn)了一個(gè)呼吸燈。
tm = pyb.Timer(3, freq=1000)pwm = tm.channel(3, mode=pyb.Timer.PWM, pin=pyb.Pin('B0'))pwm.pulse_width_percent(20)while 1: for i in range(100): pwm.pulse_width_percent(i) pyb.delay(20)
STM32H743帶有兩路DAC,分別是PA4和PA5,通過(guò)DAC我們可以輸出模擬電壓、產(chǎn)生各種波形。如下面分別使用8位(默認(rèn)情況)和12位方式控制DAC的輸出:
d1 = pyb.DAC(1)d1.write(100)d1 = pyb.DAC(1, 12)d1.write(3000)
除了直接輸出模擬電壓,也可以輸出不同波形:
三角波
d1.triangle(2048)
白噪聲
d1.noise(1000)
還可以輸出預(yù)定義的用戶波形。利用這個(gè)特點(diǎn)和STM32H7的高速特性,完全可以將它作為一個(gè)簡(jiǎn)易的波形發(fā)生器。
MicroPython還有很多功能,這里就不一一介紹了,大家可以自己運(yùn)行一下,體驗(yàn)MicrPython帶來(lái)的方便。
最后,為了測(cè)試MicroPython在STM32H743上的性能,我們做了一個(gè)計(jì)算性能對(duì)比測(cè)試,在不同的硬件平臺(tái)上,進(jìn)行加法、乘法、除法、圓周率計(jì)算,并記錄下計(jì)算消耗的時(shí)間。通過(guò)不同硬件計(jì)算時(shí)間的對(duì)比,就可以直觀的比較性能了(這可能是目前最全面的MicroPython計(jì)算性能對(duì)比測(cè)試,將目前常見(jiàn)的硬件都包括了)。
完整的測(cè)試程序
from microbit import running_timedef pi(places=100): # 3 + 3*(1/24) + 3*(1/24)*(9/80) + 3*(1/24)*(9/80)*(25/168) # The numerators 1, 9, 25, ... are given by (2x + 1) ^ 2 # The denominators 24, 80, 168 are given by (16x^2 -24x + 8) extra = 8 one = 10 ** (places+extra) t, c, n, na, d, da = 3*one, 3*one, 1, 0, 0, 24 while t > 1: n, na, d, da = n+na, na+8, d+da, da+32 t = t * n // d c += t return c // (10 ** extra)def pi_test(n=5000): t1=running_time() t=pi(n) t2=running_time() print('Pi test: ', (t2-t1)/1000, 's')def add_test(n=1000000, a = 1234, b = 5678): t1=running_time() sum = 0 for i in range(n): sum = a + b t2=running_time() print('Add test: ', (t2-t1)/1000, 's')def mul_test(n=1000000, a = 1234, b = 5678): t1=running_time() sum = 0 for i in range(n): sum = a * b t2=running_time() print('Mul test: ', (t2-t1)/1000, 's')def div_test(n=1000000, a = 1234, b = 5678): t1=running_time() sum = 0 for i in range(n): sum = a / b t2=running_time() print('Div test: ', (t2-t1)/1000, 's')print('Speed test starting...')add_test()add_test()mul_test()mul_test()div_test()div_test()pi_test()pi_test()
測(cè)試結(jié)果
主頻
整數(shù)加法
乘法
除法
圓周率
microbit
nRF51822
16M
61.888
74.075
103.935
Nucleo_F091
STM32F091
48M
19.882
25.89
51.78
82.851
PYBNano
STM32F401
84M
6.959
7.222
12.524
18.236
Nucleo_F411
STM32F411
96M
5.858
6.076
10.478
16.467
PYBV10
STM32F405
168M
3.436
3.563
6.067
10.18
STM32L476DISC
STM32L476
80M
8.586
8.989
14.913
18.932
STM32F7DISC
STM32F746
192M
1.946
2.304
3.68
4.579
Nucleo_H743
STM32H743
400M
0.856
0.942
1.534
2.835
ESP8266
80M
15.546
18.302
19.706
41.926
ESP32
240M
2.607
2.794
3.839
7.729
ESP32_psRAM
ESP32
240M
3.365
3.553
18.902
15.012
ESP32_LoBo
ESP32
240M
3.396
3.499
13.02
9.607
ESP32_psRAM_LoBo
ESP32
240M
4.228
4.15
18.902
18.757
計(jì)算結(jié)果的單位是秒
所有固件都更新到最新版本,除了Microbit、ESP32 Lobo外,固件版本都是1.9.4-479。
評(píng)論