iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0

這個議題本來是想與昨天的按鍵彈跳問題一起探討的,但由於一直在 BPI-leaf-S3 板子 BOOT 按鈕上捕捉不到彈跳,做了很多實驗,最後只好自己搞了一個按鈕開關電路:
https://ithelp.ithome.com.tw/upload/images/20231002/20140037l1Cy0fHYDu.jpg
產生了彈跳,才能實驗用軟硬體的方式來抑制彈跳效應!

昨天我們用軟硬體來降低彈跳效應,主要的癥結點在於延時,由於彈跳的發生大都發生在按鈕按下釋放的當下,因此,我們在那段時間忽略GPIO輸入值的變化,就可以避免獲取那些不正確的內容。

但這畢竟是延時,讓 CPU 不做事去睡覺!就跟前面 PWM 或者 Timer 一樣,我們是否可以利用 GPIO 中斷處理的一些特性,來降低處理彈跳延時的程式複雜度。

讓我們來看下面的例子:

from machine import Pin
SW = Pin(4, Pin.IN)

key = 0 # released

def SW_callback(pin):
    global key
    key = key + 1
 
SW.irq(handler=SW_callback, trigger=Pin.IRQ_FALLING)
# 在 SW 腳位由高電位轉低電位的當下,觸發中斷,執行 SW_callback() 函數

while True :
    if key != 0:  # pressed
        print(key)
        key = 0

理論上,按一個按鍵,應該出現一個 1 。執行後,我們發現我們發現印出好多!而且有些數值高於 1,這都是彈跳造成的。

注意:

在 while loop 中,我們對於改變 key 內容的操作,並沒使用一些同步的防護限制,主要考慮這是一個簡單的例子, 複雜的同步機制超出我們要討論的範圍,詳細的一些限制,請您參考作業系統相關的書籍。

我們再修改一下程式,在中斷中加入了時間的判斷:

import time
from machine import Pin
SW = Pin(4, Pin.IN)

key = 0 
t0 = 0
delay = 1000 # 1000 ms

def SW_callback(pin):
    global key
    global t0
    global delay
    if (key == 0):
        t1 = time.ticks_ms()
        if (t1 - t0) > delay :
            key = 1
            t0 = t1
    
SW.irq(handler=SW_callback, trigger=Pin.IRQ_FALLING)

while True :
    if key != 0:  # pressed
        print(key)
        key = 0

彈跳不見了! 您可以調整一下 delay 的數值,看看效果。

最終我們自鎖開關,開滅 LED 的程式可以改成:

import time
from machine import Pin
SW = Pin(4, Pin.IN)
LED = Pin(1, Pin.OUT)

key = 0 
t0 = 0
delay = 1000 # 1000 ms

def SW_callback(pin):
    global key
    global t0
    global delay
    if (key == 0):
        t1 = time.ticks_ms()
        if (t1 - t0) > delay :
            key = 1
            t0 = t1
    
SW.irq(handler=SW_callback, trigger=Pin.IRQ_FALLING)

LED.value(0) # turn off LED at beginning
while True :
    if key:
        LED.value(not LED.value())
        key = 0

while 主迴路是否清爽多了呢 ?


上一篇
16. GPIO輸入彈跳處理
下一篇
18.GPIO驅動能力
系列文
ESP32 Micropython 從入門到實用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言