# 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`硬件引脚(下图中带有*号的引脚)已被屏幕占用,不建议二次使用。

![img](Image/BoardPin.jpg)

  pin 0的功能如下:

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


  pin 1的功能如下:

| **功能**  |
| --------- |
| GPIO1     |
| UART1 RXD |
| SPI1 RXD  |
| JTAG TCK  |
| PWM4 OUT  |
| I2C1 SCL  |
| BT FREQ   |


  pin 2的功能如下:

| **功能**   |
| ---------- |
| GPIO2      |
| UART1 RTS  |
| SPI1 TXD   |
| JTAG TRSTN |
| PWM2 OUT   |
| SSI CLK    |

  pin 3的功能如下

| **功能**  |
| --------- |
| GPIO3     |
| UART0 TXD |
| UART1 CTS |
| SPI CSN   |
| JTAG TDI  |
| PWM5 OUT  |
| I2C1 SDA  |
| SSI DATA  |

  pin 4的功能如下:

| **功能**                          |
| --------------------------------- |
| GPIO      |
| UART0_RXD |
| JTAG_TMS  |
| PWM1_OUT  |
| I2C1_SCL  |

  pin 5的功能如下:

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

  pin 6的功能如下:

| **功能**    |
| ----------- |
| GPIO6       |
| UART1 TXD   |
| SPI0 CK     |
| PWM3 OUT    |
| I2S0 TX     |
| COEX switch |

  pin 7的功能如下:

| **功能**  |
| --------- |
| GPIO7     |
| UART1 CTS |
| SPI0 RXD  |
| PWM0 OUT  |
| I2S0 BCLK |
| BT ACTIVE |

  pin 8的功能如下:

| **功能**    |
| ----------- |
| GPIO8       |
| UART1 RTS   |
| SPI0 TXD    |
| PWM1 OUT    |
| I2S0 WS     |
| WLAN ACTIVE |

  pin 9的功能如下:

| **功能**  |
| --------- |
| GPIO9     |
| I2C0 SCL  |
| UART2 RTS |
| SDIO D2   |
| SPI0 TXD  |
| PWM0 OUT  |
| I2S0 MCLK |

  pin 10的功能如下:

| **功能**  |
| --------- |
| GPIO10    |
| I2C0 SDA  |
| UART2 CTS |
| SDIO D3   |
| SPI0 CK   |
| PWM1 OUT  |
| I2S0 TX   |

  pin 11的功能如下:

| **功能**     |
| ------------ |
| GPIO11       |
| UART2 TXD    |
| SDIO CMD     |
| SDIO RXD     |
| PWM2 OUT     |
| RF TX_EN_EXT |
| I2S0 RX      |

  pin 12的功能如下:

| **功能**     |
| ------------ |
| GPIO12       |
| SUART2 RXD   |
| SDIO CLK     |
| SDIO CSN     |
| PWM3 OUT     |
| RF RX_EN_EXT |
| I2S0 BCLK    |

  pin 13的功能如下:

| **功能**  |
| --------- |
| SSI DATA  |
| UART0 TXD |
| UART2 RTS |
| SDIO D0   |
| GPIO13    |
| PWM4 OUT  |
| I2C0 SDA  |
| I2S0 WS   |

  pin 14的功能如下:

| **功能**  |
| --------- |
| SSI CLK   |
| UART0 RXD |
| UART2 CTS |
| SDIO D1   |
| 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 	OUT
PULL_DOWN 	PULL_MAX	 PULL_NONE 	PULL_UP
init 	off		on
```

### 宏定义

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

| 宏定义        | 含义             |
| ------------- | :--------------- |
| Pin.GPIO      | 作为GPIO接口     |
| Pin.IN        | 信号输入         |
| Pin.OUT       | 信号输出         |
| Pin.PULL_DOWN | 是否接入下拉电阻 |
| Pin.NONE      | 无上拉、下拉电阻 |
| Pin.PULL_UP   | 是否接入上拉电阻 |

  注意:不是每个端口都有下面的全部属性。例如某些引脚只能输入不能输出
  其中的 Pin.OUT 为信号输出,而 Pin(2, Pin.OUT) ,就是将GPIO2 设置为输出模式

### 类

  class machine.Pin(id[, mode[, func]]])
  id :任意引脚号
  mode :引脚模式
- Pin.IN — 输入
- Pin.OUT — 输出
- None — 无上拉、下拉电阻
- Pin.PULL_UP — 上拉电阻
- Pin.PULL_DOWN — 下拉电阻
 func :引脚功能
- Pin.GPIO ——GPIO

### 定义Pin

  示例:

```python
>>> from machine import Pin
>>>
>>> gpio = Pin(2, Pin.OUT, func=Pin.GPIO) #将GPIO 2 设置为输出模式
```
### 函数
#### Pin.init([mode])
  函数说明:初始化引脚。
  mode :
- Pin.IN — 输入
- Pin.OUT — 输出

  示例:

```python
>>> from machine import Pin
>>> pin = Pin(2)
>>> pin.init(Pin.OUT) #也可以写作pin.init(Pin.OUT),初始化2号引脚的输出模式
```

#### Pin.value([value])
  函数说明:获取或设置引脚电平状态,根据引脚的逻辑电平返回0或1。

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

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

  示例:

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

#### Pin.on()

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

  示例:

```python
>>>p9=Pin(9,Pin.OUT)
>>>p9.on()
>>>p9.value()
```

#### Pin.off()

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

  示例:

```python
>>>p9=Pin(9,Pin.OUT)
>>>p9.off()
>>>p9.value()
```

## 示例
  对waffle nano的一些GPIO引脚输入或输出模式进行设置,看其电压变化如何。

```python
from machine import Pin
p9 = Pin(9, Pin.OUT)
p9.value(1)
p9.value(0)
print(p9.value())
p2 = Pin(2, Pin.IN)
print(p2.value())
```
- 第一行导入 machine 模块的硬件类 Pin
- 第二行把waffle nano默认的GPIO 9号引脚设置为输出模式
- 第三行把GPIO 9号引脚输出电压设置为高电压1
- 第五行把GPIO 9号引脚输出电压设置为低电压0
- 所以打印出的GPIO 9号引脚输出电压为低电压0
- 第七行把waffle nano默认的GPIO 2号引脚设置为输入模式
- 打印出的GPIO 2号引脚输入电压使用 from machine import Pin 导入 machine