板載按鍵KEY
1.獲取板載按鍵引腳名稱
>>> help(pyb.Pin.board) object <class 'board'> is of type type ... SW -- Pin(Pin.cpu.B3, mode=Pin.IN, pull=Pin.PULL_UP) ...
板載用戶按鍵別名:SW,芯片定義的名稱是B3.
2.獲取Switch類里面的方法
>>> help(pyb.Switch) object <class 'Switch'> is of type type value -- <function> callback -- <function>
3.基本用法
>>> switch = pyb.Switch() #構造一個Switch的對象 >>> switch() #等價於switch.value() False >>> switch() True >>> switch.value() #獲取按鍵當前狀態,True表示按下,False表示沒有按下 False >>> switch.value() True >>> switch.callback(lambda:pyb.LED(1).toggle()) #匿名函數 >>> def toggle_led(): #定義用於回調的函數 ... if switch.value(): ... pyb.delay(10) ... if switch.value(): ... pyb.LED(2).toggle() ... while switch.value():pass ... ... ... >>> switch.callback(toggle_led) #此處用於回調的函數里面是沒有括號的
switch.callback()是回調函數,功能類似C語言里的中斷函數,當按下按鍵時將自動執行這個回調函數。
在pyboard中,只定義了一個用戶按鍵。如果開發板上有多個按鍵,就需要自己去控制,而不能使用pyb.Switch()了。具體方法學習下面GPIO知識點就會了。
GPIO的使用
按鍵和LED其實就代表了GPIO的兩種最基本的使用方法:輸入和輸出,下面就完整地介紹GPIO的使用。
首先我們需要導入pyb中的Pin模塊,然后就可以定義一個Pin對象,及其使用的引腳和功能。
獲取Pin類里面的方法和相關的類
>>> help(pyb.Pin) object <class 'Pin'> is of type type init -- <function> value -- <function> off -- <function> on -- <function> irq -- <function> low -- <function> high -- <function> name -- <function> names -- <function> af_list -- <function> port -- <function> pin -- <function> gpio -- <function> mode -- <function> pull -- <function> af -- <function> mapper -- <classmethod> dict -- <classmethod> debug -- <classmethod> board -- <class 'board'> cpu -- <class 'cpu'>
構造一個X1引腳的實例以及相關的操作方法
>>> x1 = pyb.Pin('X1') >>> x1 Pin(Pin.cpu.A0, mode=Pin.IN) >>> x1.init(pyb.Pin.OUT) >>> x1 Pin(Pin.cpu.A0, mode=Pin.OUT) >>>
上面代碼中,x1就是Pin類的一個實例或者叫做一個對象,'X1'是這個GPIO的別名,它的芯片定義的名稱是Pin.cpu.A0也就是'A0'。我們使用這個Pin類里面的方法,x1.init(pyb.Pin.OUT)引腳的初始化操作也就是將引腳設置成輸入或輸出。
在MicroPython中,可以用init()函數的功能:將GPIO設置輸入或者輸出模式,其中的輸入可以設置內部的上拉下拉電阻狀態,而輸出還可以設置推挽方式輸出和開漏輸出:
>>> x1.init(pyb.Pin.OUT_PP) #設置為推挽方式輸出 >>> x1.init(pyb.Pin.OUT_OD) #設置為開漏方式輸出 >>> x1.init(pyb.Pin.IN) #設置為輸入 >>> x1.init(pyb.Pin.IN,pull=pyb.Pin.PULL_UP) #設置為輸入並使用內部上拉電阻
>>> x1.init(pyb.Pin.IN,pull=pyb.Pin.PULL_DOWN) #設置為輸入並使用內部下拉電阻
上面的Pin可以用from pyb import Pin導入,這樣子做的好處:使代碼簡潔。
>>> from pyb import Pin >>> x1 = Pin('A0') >>> x1 Pin(Pin.cpu.A0, mode=Pin.IN) >>> x1.init(Pin.OUT_PP) >>> x1 Pin(Pin.cpu.A0, mode=Pin.OUT) >>> x1.init(Pin.IN) >>> x1 Pin(Pin.cpu.A0, mode=Pin.IN) >>> x1.init(Pin.IN,Pin.PULL_UP) >>> x1 Pin(Pin.cpu.A0, mode=Pin.IN, pull=Pin.PULL_UP) >>>
需要下拉電阻時設置pull參數為:pull=PULL_DOWN,而不需要上拉下拉電阻時就設置pull=PULL_NONE。
上面是將 GPIO 的定義和模式分開設置的,這樣比較好理解。但是通常情況下,我們會將它們放在一起定義,這樣更加簡潔高效,如:
>>> from pyb import Pin >>> x1 = Pin(Pin.cpu.A0,Pin.OUT_PP) >>> x1 Pin(Pin.cpu.A0, mode=Pin.OUT) >>> x1 = Pin(Pin.cpu.A0,Pin.IN,pull=Pin.PULL_UP) >>> x1 Pin(Pin.cpu.A0, mode=Pin.IN, pull=Pin.PULL_UP)
對於GPIO的輸出值(1/0)我們可以控制其高低電平,而輸入是不可以的(除非你設置它的內部上拉電阻和下拉電阻):
>>> x1 = Pin('X1',Pin.IN) >>> x1 Pin(Pin.cpu.A0, mode=Pin.IN) >>> x1.high() >>> x1 Pin(Pin.cpu.A0, mode=Pin.IN) >>> x1.value() 0 >>> x1.init(Pin.OUT) >>> x1 Pin(Pin.cpu.A0, mode=Pin.OUT) >>> x1.high() >>> x1.value() 1
GPIO的輸入測試部分
>>> x5 = Pin('X5',Pin.IN) >>> x5.value() 0 >>> x5.value() 1 >>> x5.value() 0 >>> x5.value() 0 >>> x5.value() 0 >>> x5.value() 0 >>> x5.value() 0 >>> x5.value() 0 >>> x5.value() 1 >>> x5.value() 0 >>> x5.init(Pin.IN,pull=Pin.PULL_UP) >>> x5() 1 >>> x5() 1 >>> x5() 1 >>> x5() 1 >>> x5() 1 >>> x5() 1 >>> x5() 1 >>> x5() 1 >>> x5.init(Pin.IN,pull=Pin.PULL_DOWN) >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5.init(Pin.IN,pull=Pin.PULL_NONE) >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 1 >>> x5() 0 >>> x5() 1 >>> x5() 0
結論:對於輸入模式下的通用輸入引腳(Pin.IN)的電平狀態是不確定的,而使用上拉電阻時電平狀態一直是高電平狀態,使用下拉電阻時就一直是低電平,而Pin.PULL_NONE和通用輸入是一樣的,引腳的電平狀態也無法確定。(高阻態)
GPIO的輸出測試部分
>>> x5 = Pin('X5',Pin.OUT) >>> x5 Pin(Pin.cpu.A4, mode=Pin.OUT) >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5.init(Pin.OUT_PP) >>> x5 Pin(Pin.cpu.A4, mode=Pin.OUT) >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5.high() >>> x5() 1 >>> x5.low() >>> x5() 0 >>> x5.on() >>> x5() 1 >>> x5.off() >>> x5() 0 >>> x5.init(Pin.OUT_OD) >>> x5 Pin(Pin.cpu.A4, mode=Pin.OPEN_DRAIN) >>> x5() 0 >>> x5.high() >>> x5() 1 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 0 >>> x5() 1 >>> x5() 0 >>> x5() 0 >>> x5() 1 >>> x5() 0 >>> x5() 0 >>> x5() 0
結論:GPIO輸出模式通用模式時的輸出電平一直為低電平,相關輸出操作方法(GPIO輸出相關的方法:x1.high()、x1.low()、x1.on()、x1.off())也是可以直接使用的,但是在開漏模式下輸出引腳的電平狀態是不確定的,需要外接一個上拉電阻,才可以輸出穩定的高電平。
推挽輸出:可以輸出高、低電平。
開漏輸出:輸出端相當於三極管的集電極,要得到穩定的電平狀態只能是依靠上拉電阻得到穩定的高電平,電壓取決於你的上拉電阻,所有好處是可以輸出可以調節的電壓。
像上面電平一直浮動的狀態叫做高阻態。
詳細說明地址:推挽輸出和開漏輸出
引腳中斷的方法:
Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), priority=1, wake=None, hard=False)
中斷相關資料地址:https://www.cnblogs.com/iBoundary/p/11508565.html
對於GPIO的引腳電平狀態我們可以使用value()或者直接x1()讀取
af,當mode是Pin.AF_PP或Pin.AF_OD時,可以選擇第二功能索引或名稱
af_list()
返回GPIO的第二功能列表,如:
>>> pyb.Pin.af_list(pyb.Pin('X1')) [Pin.AF1_TIM2, Pin.AF1_TIM2, Pin.AF2_TIM5, Pin.AF3_TIM8, Pin.AF7_USART2, Pin.AF8_UART4]
通過這個函數,我們可以具體查看一個GPIO有哪些第二功能。
af()
返回GPIO第二功能索引值,如果沒有使用第二功能將返回0,否則返回實際的索引值。
注意這個索引值並不是對應af_list()函數返回的列表,而是控制器手冊中的第二功能映射表。PYB V10使用的控制器是STM32F405RG,可以參考它的數據手冊第61頁的“Table 9.Alternate function mapping”。
如,PA11是AF10_OTG_FS_DM功能:
>>> pyb.Pin.af_list(pyb.Pin('A11')) [Pin.AF1_TIM1, Pin.AF7_USART1, Pin.AF9_CAN1] >>> pyb.Pin.af(pyb.Pin('A11')) 10
SC
手冊地址:https://www.st.com/resource/en/datasheet/stm32f405rg.pdf
gpio()
當前GPIO關聯寄存器的基本地址。
mode()
設置或獲取GPIO的模式,mode含義可以參考init()函數中相關參數的說明。
name()
返回GPIO的名稱。
names()
返回GPIO和別名。
pin()
返回引腳在端口中的序號。
port()
返回端口序號。
>>> sw.port()
1
端口A的序號是0,端口B的序號是1,端口C的序號是2,以此類推。按鍵sw對應的引腳是B3,因此返回值是1。
pull()
引腳的上拉狀態。具體參數含義參考init()函數中pull參數。