# GPIO

- [GPIO接口](#gpio接口)
  - [概要](#概要)
    - [什么是GPIO](#什么是gpio)
    - [预备知识](#预备知识)
      - [电信号](#电信号)
      - [模拟信号](#模拟信号)
    - [数字信号](#数字信号)
      - [高低电平](#高低电平)
      - [上升沿 下降沿](#上升沿-下降沿)
  - [GPIO端口通用方法集合](#gpio端口通用方法集合)
- [GPIO引脚定义](#gpio引脚定义)
- [machine.Pin API详解](#machinepin-api详解)
- [宏定义](#宏定义)
- [类](#类)
- [定义Pin](#定义pin)
- [函数](#函数)
    - [Pin.init([mode])](#pininitmode)
    - [Pin.value([value])](#pinvaluevalue)
    - [Pin.on()](#pinon)
    - [Pin.off()](#pinoff)
- [示例](#示例)

## GPIO接口

### 概要

  本节讲解`machine` 模块中的`Pin`类以及数字信号的相关概念。

#### 什么是GPIO 

- GPIO(General-purpose input/output)即通用型输入输出。
- GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。

#### 预备知识

##### 电信号


  信号是运载消息的工具,是消息的载体。从广义上讲,它包含光信号、声信号和电信号等。**电信号是指随着时间而变化的电压或电流**,因此在数学描述上可将它表示为时间的函数,并可画出其波形。由于非电的物理量可以通过各种传感器较容易地转换成电信号,而电信号又容易传送和控制,所以使其成为应用最广的信号。

  在电子线路中,我们将电信号进行如下的划分:
- 模拟信号
- 数字信号

![](Image/analog_vs_digitial.jpeg)

##### 模拟信号

  模拟信号是指信息参数在给定范围内表现为**连续**的信号。

  广播的声音信号,或图像信号等生活中许多常见的信号,都是模拟信号。

##### 数字信号

  数字信号是指幅度的取值是离散的,幅值表示被限制在有限个数值之内。二进制码就是一种数字信号。在这种二进制体系中,我们用 0 表示 `低电平`, 1表示 `高电平`。很可能你会问,高低电平指什么?

##### 高低电平

  你可以简单的理解为较高的电压为高电平,较低的电压自然就是低电平。当然,肯定有一套判定高低电平的准则:

**一般规定低电平为0~ 0.25V,高电平为3.5~5V。**

  当然对于有些不同的芯片或者电路模组,对高电平或低电平的定义可能会有所差异。

##### 上升沿 下降沿

![img](Image/signal.png)

  当低电平突然跃升为高电平时,电信号的变化时间极快,几乎呈直角,从低电平直线攀升至高电平,这个电平跳变的过程我们称之为**上升沿**

  当高电平突然下降为低电平时,电信号的变化时间极快,几乎呈直角,从高电平直线跌入低电平,这个电平跳变的过程我们称之为**下降沿**

  同时从上面这张图你也可以看出,在数字信号中,我们的电压变化理论上只有 低电平0 或 高电平1,因此我们的数字信号能够更好的被计算机所理解,并进行快速的运算。

#### GPIO端口通用方法集合

  GPIO控制器通过分组的方式管理所有GPIO管脚,包括:
- 设置管脚方向: 方向可以是输入或者输出(暂不支持高阻态) 
- 读写管脚电平值: 电平值可以是低电平或高电平

## GPIO引脚定义

  GPIO拥有0~14 共15个引脚。

  其中引脚号直接对应于Waffle Nano 硬件实际物理引脚排布。

  并且注意,在硬件屏幕接入到Waffle Nano开发板上时,引脚号为`IO6`、`IO7`、`IO8`、`IO11`硬件引脚(下图中带有*号的引脚)已被屏幕占用,不建议二次使用。`IO2`在程序上传时需要保持拉低状态。`IO9`、`IO10`作为内部IIC总线通信使用,内部将始终存在上拉电阻,保持上拉状态。`IO3`、`IO4`作为编程串口被持续占用,板子未将此引出。

![img](Image/BoardPin.jpg)

  pin 0的功能如下:

| **功能**  |
| --------- |
| GPIO0     |
| UART1 TXD |
| SPI1 CK   |
| PWM3 OUT  |
| I2C1 SDA  |


  pin 1的功能如下:

| **功能**  |
| --------- |
| GPIO1     |
| UART1 RXD |
| SPI1 RXD  |
| PWM4 OUT  |
| I2C1 SCL  |


  pin 2的功能如下:

| **功能**   |
| ---------- |
| GPIO2      |
| SPI1 TXD   |
| PWM2 OUT   |



  pin 5的功能如下:

| **功能**  |
| --------- |
| GPIO5     |
| UART1 RXD |
| SPI0 CSN  |
| PWM2 OUT  |
| I2C0 MCLK |

  pin 6的功能如下:

| **功能**    |
| ----------- |
| GPIO6       |
| UART1 TXD   |
| SPI0 CK     |
| PWM3 OUT    |

  pin 7的功能如下:

| **功能**  |
| --------- |
| GPIO7     |
| SPI0 RXD  |
| PWM0 OUT  |

  pin 8的功能如下:

| **功能**    |
| ----------- |
| GPIO8       |
| SPI0 TXD    |
| PWM1 OUT    |

  pin 9的功能如下:

| **功能**  |
| --------- |
| GPIO9    |
| I2C0 SDA  |
| SPI0 CK   |
| PWM1 OUT  |

  pin 10的功能如下:

| **功能**  |
| --------- |
| GPIO10     |
| I2C0 SCL  |
| SPI0 TXD  |
| PWM0 OUT  |


  pin 11的功能如下:

| **功能**     |
| ------------ |
| GPIO11       |
| UART2 TXD    |
| PWM2 OUT     |

  pin 12的功能如下:

| **功能**     |
| ------------ |
| GPIO12       |
| PWM3 OUT     |

  pin 13的功能如下:

| **功能**  |
| --------- |
| UART0 TXD |
| GPIO13    |
| PWM4 OUT  |
| I2C0 SDA  |

  pin 14的功能如下:

| **功能**  |
| --------- |
| UART0 RXD |
| GPIO14    |
| PWM5 OUT  |
| I2C0 SCL  |

## machine.Pin API详解

  使用`from machine import Pin`导入 `machine` 模块的硬件类 `Pin`
  再使用 `TAB` 按键来查看 `Pin` 中所包含的内容:

```python
>>> from machine import Pin
>>>Pin.
value           GPIO            IN              INT_EDGE
INT_LEVEL       IRQ_FALLING     IRQ_RISING      OUT
PULL_DOWN       PULL_NONE       PULL_UP         init
irq             off             on              pull
```

### 宏定义

  下面的宏定义用于配置pin,也就是将对应编号的真实的管脚配置成输入或者输出或者其他模式

| 宏定义        | 含义             |
| ------------- | :--------------- |
| Pin.GPIO      | 作为GPIO接口     |
| Pin.OUT       | 信号输出         |
| Pin.IN        | 信号输入         |
| Pin.PULL_DOWN | 是否接入下拉电阻 |
| Pin.PULL_NONE      | 无上拉、下拉电阻 |
| Pin.PULL_UP   | 是否接入上拉电阻 |
| Pin.INT_EDGE   | 边沿触发中断 |
| Pin.INT_LEVEL   | 电平触发中断 |
| Pin.IRQ_RISING   | 上升沿触发 |
| Pin.IRQ_FALLING   | 下降沿触发 |




### 类

  class machine.Pin(id,mode,pull)
可传入参数:

- `id`:引脚号
- `mode`:引脚模式
  - Pin.IN — 输入
  - Pin.OUT — 输出
- `pull`:拉电阻模式
  - Pin.PULL_NONE — 无上拉、下拉电阻
  - Pin.PULL_UP — 上拉电阻
  - Pin.PULL_DOWN — 下拉电阻


### 构造Pin

  示例:

```python
from machine import Pin
gpio = Pin(13, dir=Pin.OUT,pull=Pin.PULL_DOWN) #将GPIO 13 设置为输出模式,并且进入下拉模式
```


### 函数

#### Pin.init(mode)

  函数说明:初始化引脚。

  mode:

- Pin.IN — 输入
- Pin.OUT — 输出

  示例:

```python
from machine import Pin
pin = Pin(13)
pin.init(Pin.OUT) #初始化13号引脚为输出模式
```

#### Pin.value(value)

  函数说明:获取或设置引脚电平状态,根据引脚的逻辑电平返回0或1。

  注意:不带参数时是读取输出电平,带参数时是设置输出电平。

  value :可以是 True / False ,也可以是 1 / 0 。

  示例:

```python
>>> pin13 = Pin(13,Pin.OUT) #设置13号引脚为输出模式
>>> pin13.value() #读取13号引脚输出电平
0
>>> pin13.value(True) #设置13号引脚输出电平为高电平
>>> pin13.value()
1
>>> pin13.value(0) #设置13号引脚输出电平为低电平
>>> pin13.value()
0
```

#### Pin.on()

  函数说明:设置引脚输出电平状态返回1。

  示例:

```python
>>>p13=Pin(13,Pin.OUT)
>>>p13.on()
>>>p13.value()
```

#### Pin.off()

  函数说明:设置引脚输出电平状态为0。

  示例:

```python
>>>p13=Pin(13,Pin.OUT)
>>>p13.off()
>>>p13.value()
```

#### Pin.pull(value)

  函数说明:获取或设置引脚拉电阻状态,根据引脚的拉电阻状态返回0(无拉电阻)或1(上拉电阻)或2(下拉电阻)。

  注意:1.不带参数时是读取引脚拉电阻状态,带参数时是设置引脚拉电阻状态。2.`IO9`和`IO10`默认为恒定上拉状态。

  value :

  - Pin.PULL_NONE
    0(无拉电阻)
  - Pin.PULL_UP
    1(上拉电阻)
  - Pin.PULL_DOWN
    2(下拉电阻)

  示例:
```python
>>>p13=Pin(13,Pin.OUT)
>>>p13.pull(Pin.PULL_DOWN) #设置13号引脚为下拉状态
>>>p13.pull() #查看此时引脚拉状态
0
```


#### Pin.irq(callback, trigger, int_type)

  函数说明:设置引脚中断

  参数说明:`callback`为中断触发函数,当检测到有中断被触发时将会运行此函数。`trigger`为中断触发条件,只有满足条件时中断才被触发。`int_type`为中断触发方式。

  参数值域:

  - callback
    - 一般函数
  - trigger
    - Pin.IRQ_RISING
    - Pin.IRQ_FALLING 
  - int_type
    - Pin.INT_EDGE
    - Pin.INT_LEVEL


  示例:

```python
from machine import Pin #导入Pin 库
pin = Pin(0, dir=Pin.IN,pull=Pin.PULL_UP) #构造Pin对象,使其作用于0号引脚,将其设置为输入模式,并且设置为上拉状态
def callback(p): #设置回调函数,每次检测到中断触发时所运行的函数,其中p为触发中断的Pin对象
    print('pin change: ', p)
ret = pin.irq(callback, trigger=Pin.IRQ_RISING, int_type=Pin.INT_EDGE) #将pin设置为一个上升沿触发的中断,其触发方式是边沿触发中断,能检测pin对应的实际物理引脚的电平状态的突变。

```