《DNK210使用指南 -CanMV版 V1.0》第十八章 machine.Timer類實驗

正点原子發表於2024-08-09

第十八章 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 例程功能

  1. 建立一個超時週期為500毫秒的週期定時器,並再其超時回撥函式中控制紅色LED切換亮滅狀態
  2. 按下KEY0按鍵後啟動週期定時器計時
  3. 按下KEY1按鍵後停止週期定時器計時

18.2.2 硬體資源

  1. 雙色LED
    LEDR - IO24
  2. 獨立按鍵
    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物件被停止計時而保持當前的狀態,不再閃爍。

相關文章