第十八章 machine.Timer類實驗
1)實驗平臺:正點原子DNK210開發板
2)章節摘自【正點原子】DNK210使用指南 - CanMV版 V1.0
3)購買連結:https://detail.tmall.com/item.htm?&id=782801398750
4)全套實驗原始碼+手冊+影片下載地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html
5)正點原子官方B站:https://space.bilibili.com/394620890
6)正點原子K210技術交流企鵝群:605557868
本章將介紹machine模組中的Timer類,即定時器類。透過本章的學習,讀者將學習到machine模組中Timer類的使用。
本章分為如下幾個小節:
18.1 machine.Timer類介紹
18.2 硬體設計
18.3 程式設計
18.4 執行驗證
18.1 machine.Timer類介紹
machine.Timer類是machine模組內提供的類,該類主要用於訪問和控制Kendryte K210硬體上的定時器,硬體定時器可以用來定時觸發任務或者處理任務,當到了設定的時間,硬體定時器便會觸發中斷,並且硬體定時器的計時精度相比軟體定時器要高得多。CanMV中的machine.Timer類定義了在給定時間段(或在一段延遲後執行一次回撥)指定回撥的基本操作,並同時可以配置machine.PWM類實現使用硬體定時器輸出PWM,其中machine.PWM類將在後續的章節中進行講解。
machine.Timer類提供了Timer建構函式,用於建立一個Timer物件,Timer建構函式如下所示:
class Timer(id, channel, mode=Timer.MODE_ONE_SHOT, period=1000, unit=Timer.
UNIT_MS, callback=None, arg=None, start=True, priority=1, div=0)
透過Timer建構函式可以透過指定引數建立並初始化一個Timer物件。
id指的是定時器的編號,可以是Timer.TIMER0、Timer.TIMER1或Timer.TIMER2,它們分別對應Kendryte K210硬體上的定時器0、定時器1和定時器2。
channel指的是定時器的通道編號,可以是Timer.CHANNEL0、Timer.CHANNEL1、Timer.CHANNEL2或Timer.CHANNEL3,它們分別對應Kendryte K210硬體定時器的通道0至通道3。
mode指的是Timer物件的模式,當為Timer.MODE_ONE_SHOT時,Timer物件會在超時一次後自動停止(單次定時器),當為Timer.MODE_PERIODIC時,Timer物件會在超時後自動重新開始計時,直到被手動停止計時(週期定時器),當為Timer.MODE_PWM時,Timer物件將用於配合machine.PWM類生成PWM。
period指的是Timer物件的超時時間,具體的時間單位由unit引數決定。
unit指的時Timer物件超時時間的單位,可以是Timer.UNIT_S、Timer.UNIT_MS、Timer.UNIT_US或Timer.UNIT_NS,它們分別對應秒、毫秒、微秒和納秒。
callback指的是Timer物件的超時回撥函式,Timer物件將在計時超時後指定該函式,需要注意的是,該函式是在中斷上下文中被指定的。
arg指的是傳遞給Timer物件超時回撥函式的引數。
start指的是是否在Timer物件構造成功後便開始計時,當為True時,Timer物件會在被構造成功後便開始計時,當為False時,Timer物件在被構造成功後並不會開始計時。
priority指的是Timer物件對應硬體定時器的中斷優先順序,可以指1~7,數值越小,中斷優先等級越高。
div指的是Timer物件對應硬體定時器的分頻係數。
Timer建構函式的使用示例如下所示:
from machine import Timer
def timer_timeout_cb(timer):
print("Timer timeout!")
timer0 = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.
MODE_PERIODIC, period=500, unit=Timer.
UNIT_MS, callback=timer_timeout_cb, arg={"id": Timer.TIMER0}, start=False, priority=1, div=0)
machine.Timer類為Timer物件提供了start()方法,用於開啟Timer物件的計時,start()方法如下所示:
Timer.start()
start()方法用於開啟Timer物件的計時,方法執行後,Timer物件便開始計時。
start()方法的使用示例如下所示:
from machine import Timer
timer = Timer(Timer.TIMER0, Timer.CHANNEL0, start=False)
timer.start()
machine.Timer類為Timer物件提供了stop()方法,用於停止Timer物件的計時,stop()方法如下所示:
Timer.stop()
stop()方法用於停止Timer物件的計時,方法執行後,Timer物件便會停止計時,也不會再執行超時回撥函式。
stop()方法的使用示例如下所示:
from machine import Timer
timer = Timer(Timer.TIMER0, Timer.CHANNEL0, start=True)
timer.stop()
machine.Timer類為Timer物件提供了restart()方法,用於重新開始Timer物件的計時,restart()方法如下所示:
Timer.restart()
restart()方法用於重新開始Timer物件的計時,不論Timer物件是否處於計時狀態,當restart()方法執行後,Timer物件便會重新開始計時。
restart()方法的使用示例如下所示:
from machine import Timer
timer = Timer(Timer.TIMER0, Timer.CHANNEL0, start=True)
timer.restart()
18.2 硬體設計
18.2.1 例程功能
- 建立一個超時週期為500毫秒的週期定時器,並再其超時回撥函式中控制紅色LED切換亮滅狀態
- 按下KEY0按鍵後啟動週期定時器計時
- 按下KEY1按鍵後停止週期定時器計時
18.2.2 硬體資源
- 雙色LED
LEDR - IO24 - 獨立按鍵
KEY0按鍵 - IO18
KEY1按鍵 - IO19
18.2.3 原理圖
本章實驗內容,主要講解machine.Timer類的使用,無需關注原理圖。
18.3 程式設計
18.3.1 machine.Timer類
有關machine.Timer類的介紹,請見第18.1小節《machine.Timer類介紹》。
18.3.2 程式流程圖
圖18.3.2.1 machine.Timer類實驗流程圖
18.3.3 main.py程式碼
main.py中的指令碼程式碼如下所示:
from board import board_info
from fpioa_manager import fm
from maix import GPIO
import time
from machine import Timer
fm.register(board_info.LEDR, fm.fpioa.GPIO0)
fm.register(board_info.KEY0, fm.fpioa.GPIOHS0)
fm.register(board_info.KEY1, fm.fpioa.GPIOHS1)
ledr = GPIO(GPIO.GPIO0, GPIO.OUT, value=1)
key0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)
key1 = GPIO(GPIO.GPIOHS1, GPIO.IN, GPIO.PULL_UP)
# Timer超時回撥函式
def timer_timeout_cb(timer):
arg = timer.callback_arg()
if arg["id"] == Timer.TIMER0:
ledr.value(not ledr.value())
# 構造Timer物件
timer0 = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=500, unit=Timer.
UNIT_MS, callback=timer_timeout_cb, arg={"id": Timer.TIMER0}, start=False, priority=1, div=0)
while True:
if key0.value() == 0:
time.sleep_ms(20)
if key0.value() == 0:
# 啟動Timer
timer0.start()
while key0.value() == 0:
pass
elif key1.value() == 0:
time.sleep_ms(20)
if key1.value() == 0:
# 停止Timer
timer0.stop()
while key1.value() == 0:
pass
time.sleep_ms(10)
可以看到,首先是初始化使用到獨立按鍵和LED的IO,然後定義了一個函式作為Timer的超時回撥函式,函式主要實驗了變更LED狀態的功能。
接著便構造了一個Timer物件,Timer物件使用的是硬體定時器0的通道0,並且是一個每間隔500毫秒超時一次的週期定時器。
最後就是在一個迴圈中讀取按鍵的狀態,當讀取到KEY0按鍵被按下,則啟動Timer物件計時,當讀取到KEY1按鍵被按下,則停止Timer物件計時。
18.4 執行驗證
將DNK210開發板連線CanMV IDE,並點選CanMV IDE上的“開始(執行指令碼)”按鈕後,此時,若按下KEY0按鍵,則可以看到紅色LED因Timer物件以500毫秒的週期超時而以1000毫秒的週期進行亮滅閃爍,若接著按下KEY1按鍵,則可以看到紅色LED因Timer物件被停止計時而保持當前的狀態,不再閃爍。