Pyboard基础功能探索---按键、GPIO

板载按键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参数。

原文地址:https://www.cnblogs.com/iBoundary/p/11504172.html