<button id="ssm6u"><optgroup id="ssm6u"></optgroup></button>
  • 跳轉至

    定時器

    概要

    本文介紹了定時器與回調函數的概念,以及如何在MicroPython-ESP32中使用定時器,最后用定時器控制LED進行周期的閃爍。

    keywords Timer callback led blink

    什么是定時器?

    定時器你可以理解為一個鬧鐘,你可以設定特定時間之后執行某件事情,也可以周期的執行某件事情,比如每隔1s鐘變換一下LED的亮燈狀態。

    定時器與utime模塊中的sleep延時函數最大區別在于,延時函數期間,CPU就如同進入了睡眠,之后的事情只有等睡醒之后再做,這種情況我們稱之為阻塞, 睡覺阻塞了cpu去完成其他的任務,必須等待CPU睡醒;而定時器是非阻塞的,在未到達定時器定時周期結束之前,CPU可以去做別的事情,等到定時器計時完畢,便會去通知CPU,CPU再去執行回調函數 (在你設定鬧鐘之前,你決定要在鬧鐘響了之后去做的事情)。

    定時器每個周期都會產生一次中斷,然后調用特定的 回調函數callback, 定時器中斷屬于內部中斷.

    中斷

    CPU的中斷分為很多種,不同的中斷擁有不同的優先級別。當多個中斷同時發生時,計算機按照優先級來以此處理

    Timer-常用API

    Timer類被封裝在machine模塊中。

    from machine import Timer
    

    實例化一個Timer對象,傳入一個任意正整數作為ID。

    例如:

    timer = Timer(1)
    

    然后需要 初始化定時器:

    timer.init(period=1000, mode=Timer.PERIODIC , callback=callback)
    
    • period 定時器執行的周期,單位是ms, 隔period ms 執行一次。 period取值范圍: 0 < period <= 3435973836

    • mode 定時器的執行模式

    • Timer.PERIODIC 周期執行

    • Timer.ONE_SHOT 只執行一次,執行完了定時器就結束

    • callback: 定時器的回調函數,傳入的一個參數是timer

    如果你想在callback函數里面傳入其他參數,可以參照下方 定時器控制LED閃爍 中的 Lambda表達式 的方法。

    timer.init(period=period, mode=Timer.PERIODIC, callback=lambda t:led_toggle(led_pin))
    

    最后,定時器使用完了記得要釋放定時器資源,鍵盤中斷并不會銷毀定時器,定時器會一直產生回調函數。

    timer.deinit()
    

    定時器控制LED閃爍

    定時器控制LED閃爍 timer_led_blink.py

    from machine import Timer,Pin
    import utime
    
    
    def toggle_led(led_pin):
        '''
        LED狀態反轉
        '''
        led_pin.value(not led_pin.value())
    
    
    
    def led_blink_timed(timer, led_pin, freq=10):
        '''
        led 按照特定的頻率進行閃爍
        LED閃爍周期 = 1000ms / 頻率
        狀態變換間隔(period) = LED閃爍周期/ 2 
        '''
        # 計算狀態變換間隔時間 ms
        period = int(0.5 * 1000 / freq)
        # 初始化定時器
        # 這里回調是使用了lambada表達式,因為回調函數需要傳入led_pin
        timer.init(period=period, mode=Timer.PERIODIC, callback=lambda t:toggle_led(led_pin))
    
    
    # 聲明引腳 D2 作為LED的引腳
    led_pin = Pin(2, Pin.OUT)
    timer = Timer(1)    # 創建定時器對象
    led_blink_timed(timer, led_pin, freq=20)
    

    效果展示:

    工程經驗

    注意,不要在定時器回調函數里面創建變量,可以使用 全局變量 global,因為定時器每次都創建變量比較消耗內存。

    在毫秒級周期執行的定時器回調函數里面,

    千萬不要在終端里面Print

    千萬不要在終端里面Print

    千萬不要在終端里面Print

    因為在終端Print打印會干擾Timer回調函數執行頻率。而且定時器在產生按鍵中斷CTRL+C的時候 并不會注銷,如果定時器回調函數一直在打印,它會一直打印 占用REPL資源,影響你使用REPL。


    韩国精品无码一区二区三区,精品无码一区二区三区AV,欧洲丰满美熟女乱又伦AV,亚洲午夜久久久影院伊人