11、树莓派UART与GPIO硬件全解析

树莓派UART与GPIO硬件全解析

1. UART传输问题

在UART(通用异步收发传输器)传输过程中,存在一些可能导致问题的因素:
- 线路噪声可能导致接收到错误的XON/XOFF字符,从而造成数据丢失或链路锁定。
- 远端接收XOFF字符的延迟,若接收缓冲区已满,可能会导致数据丢失。
- XON和XOFF字符不能用于传输链路中的数据,这对二进制数据传输是个问题。

问题1 - 3可能导致链路锁定或数据丢失,而问题4可通过缓冲区及时通知另一端避免溢出。

2. 树莓派UART支持情况

树莓派支持两种UART:
| UART | 硬件 | 节点 | GPIO | ALT |
| — | — | — | — | — |
| UART0 | PL011 | /dev/ttyAMA0 | 14 & 15 | 0 |
| UART1 | Mini UART | /dev/ttyS0 | 14 & 15 | 5 |

使用哪种UART取决于树莓派的型号。最初,B型和A型树莓派使用PL011(/dev/ttyAMA0)作为控制台,Mini UART(/dev/ttyS0)功能有限。随着Pi 3和Pi Zero W增加了无线和蓝牙功能,PL011被用于支持蓝牙和WIFI,Mini UART则用于串行控制台,其他型号仍首选PL011作为控制台。

3. 确定使用的串行设备

可通过以下步骤确定使用的串行设备:
1. 查看内核命令行:

$ cat /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 ...
  1. 列出串行设备:
$ ls -l /dev/serial0
lrwxrwxrwx 1 root root 5 Jun 19 22:04 /dev/serial0 -> ttyS0
  1. 查看实际设备:
$ ls -l /dev/ttyS0
crw--w---- 1 root tty 4, 64 Jun 19 22:04 /dev/ttyS0

若输出显示 /dev/serial0 指向 /dev/ttyS0 ,则表示使用的是Mini UART。

4. 禁用串行控制台

若要将串行设备用于非控制台目的,需禁用控制台,可按以下步骤操作:
1. 以root身份运行 raspi-config

# raspi-config
  1. 向下移动光标选择“Interface Options”并按回车键。
  2. 选择“ ”禁用控制台并按回车键。
  3. 向下移动光标选择“Serial”并按回车键。
  4. 最后,根据提示选择是否重启,内核控制台更改需要重启。
5. 不同型号树莓派的串行控制台
  • Raspberry Pi 3 :启动时连接串行端口并启用控制台,启动后显示登录提示,如:
Raspbian GNU/Linux 9 rpi3bplus ttyS0
rpi3bplus login: pi
Password:

尽管 /dev/serial0 可能不存在,但Raspbian会使用 /dev/ttyS0 (Mini UART)作为控制台。
- Raspberry Pi Zero :启动时启用串行控制台,确认使用PL011(/dev/ttyAMA0)作为控制台,登录提示如下:

Raspbian GNU/Linux 8 raspberrypi ttyAMA0
raspberrypi login: pi
Password:
6. PL011与Mini UART的差异
  • Mini UART :FIFOs较小,不支持硬件流控制,在高数据速率下易丢失数据,波特率与VPU时钟相关,还存在以下不足:
  • 无中断检测
  • 无帧错误检测
  • 无奇偶校验位支持
  • 无接收超时中断
  • 无DCD、DSR、DTR或RI信号
  • PL011 UART :不支持红外数据协会(IrDA)、串行红外(SIR)协议编解码器、直接内存访问(DMA)以及DCD、DSR、DTR和RI信号,但支持以下特性:
  • 独立的16×8发送和16×12接收FIFO缓冲区
  • 可编程波特率发生器
  • 错误起始位检测
  • 线路中断生成和检测
  • 支持CTS和RTS控制功能
  • 可编程硬件流控制
  • 完全可编程的串行接口特性,包括数据位、奇偶校验位、停止位和波特率的设置
7. UART GPIO引脚

默认情况下,发送和接收引脚为GPIO 14(TX)和15(RX),对应GPIO头的P1 - 08和P1 - 10引脚。当PL011设备可用时,选择备用功能5可使硬件流控制信号出现在GPIO头上。具体连接如下表所示:
| 功能 | GPIO | P1/P5 | ALT | 方向 | 描述 |
| — | — | — | — | — | — |
| TXD | 14 | P1 - 08 | 0 | 输出 | DTE发送数据 |
| RXD | 15 | P1 - 10 | 0 | 输入 | DTE接收数据 |
| RTS | 17 | P1 - 11 | 5 | 输出 | 请求发送 |
| CTS | 30 | P1 - 36 | 5 | 输入 | 清除发送 |

若要访问UART的CTS和RTS信号,需将GPIO 30和17配置为备用功能5。

8. GPIO硬件概述

通用输入输出(GPIO)是树莓派用户关注的焦点,它是连接外部世界的接口。树莓派的GPIO引脚可通过软件重新配置,例如GPIO 14可作为输入、输出或串行端口的TX数据线。

不过,树莓派的GPIO接口使用的是较弱的3.3V CMOS接口,引脚易受静电放电(ESD)损坏,驱动能力较弱(2 - 16 mA),且GPIO电源需从总备用电流容量中分配(原Pi Model B为50 mA)。使用转接板可解决这些问题,但成本较高,因此有必要寻找低成本且有效的自制解决方案。

9. GPIO引脚与标识

现代树莓派模型的GPIO连接分为奇数引脚和偶数引脚,具体如下:
- 奇数引脚
| 引脚 | GPIO | 名称 | 描述 |
| — | — | — | — |
| P1 - 01 | +3.3 V | 电源,来自稳压器 |
| P1 - 03 | GPIO - 2 | I2C SDA1(带1.8 kΩ上拉电阻) |
| P1 - 05 | GPIO - 3 | I2C SCL1(带1.8 kΩ上拉电阻) |
| P1 - 07 | GPIO - 4 | GPIO_GCLK | 通用时钟输出或1 - Wire |
| P1 - 09 | 接地 |
| P1 - 11 | GPIO - 17 | GPIO_GEN0 |
| P1 - 13 | GPIO - 27 | GPIO_GEN2 |
| P1 - 15 | GPIO - 22 | GPIO_GEN3 |
| P1 - 17 | +3.3 V | 电源,来自稳压器 |
| P1 - 19 | GPIO - 10 | SPI_MOSI |
| P1 - 21 | GPIO - 9 | SPI_MISO |
| P1 - 23 | GPIO - 11 | SPI_CLK |
| P1 - 25 | 接地 |
| P1 - 27 | ID_SD | I2C ID EEPROM数据 |
| P1 - 29 | GPIO - 5 |
| P1 - 31 | GPIO - 6 |
| P1 - 33 | GPIO - 13 |
| P1 - 35 | GPIO - 19 |
| P1 - 37 | GPIO - 26 |
| P1 - 39 | 接地 |
- 偶数引脚
| 引脚 | GPIO | 名称 | 描述 |
| — | — | — | — |
| P1 - 02 | +5 V | 电源 |
| P1 - 04 | +5 V | 电源 |
| P1 - 06 | 接地 |
| P1 - 08 | GPIO - 14 | TXD0 | UART发送 |
| P1 - 10 | GPIO - 15 | RXD0 | UART接收 |
| P1 - 12 | GPIO - 18 | GPIO_GEN1 |
| P1 - 14 | 接地 |
| P1 - 16 | GPIO - 23 | GPIO_GEN4 |
| P1 - 18 | GPIO - 24 | GPIO - GEN5 |
| P1 - 20 | 接地 |
| P1 - 22 | GPIO - 25 | GPIO_GEN6 |
| P1 - 24 | GPIO - 8 | SPI_CE0_N |
| P1 - 26 | GPIO - 7 | SPI_CE1_N |
| P1 - 28 | ID_SC | I2C ID EEPROM时钟 |
| P1 - 30 | 接地 |
| P1 - 32 | GPIO - 12 |
| P1 - 34 | 接地 |
| P1 - 36 | GPIO - 16 |
| P1 - 38 | GPIO - 20 |
| P1 - 40 | GPIO - 21 |

10. GPIO交叉参考

为方便查找GPIO对应的引脚号,提供了以下交叉参考表:
| GPIO | 引脚 | GPIO | 引脚 | GPIO | 引脚 | GPIO | 引脚 |
| — | — | — | — | — | — | — | — |
| GPIO - 2 | P1 - 03 | GPIO - 9 | P1 - 21 | GPIO - 16 | P1 - 36 | GPIO - 23 | P1 - 16 |
| GPIO - 3 | P1 - 05 | GPIO - 10 | P1 - 19 | GPIO - 17 | P1 - 11 | GPIO - 24 | P1 - 18 |
| GPIO - 4 | P1 - 07 | GPIO - 11 | P1 - 23 | GPIO - 18 | P1 - 12 | GPIO - 25 | P1 - 22 |
| GPIO - 5 | P1 - 29 | GPIO - 12 | P1 - 32 | GPIO - 19 | P1 - 35 | GPIO - 26 | P1 - 37 |
| GPIO - 6 | P1 - 31 | GPIO - 13 | P1 - 33 | GPIO - 20 | P1 - 38 | GPIO - 27 | P1 - 13 |
| GPIO - 7 | P1 - 26 | GPIO - 14 | P1 - 08 | GPIO - 21 | P1 - 40 |
| GPIO - 8 | P1 - 24 | GPIO - 15 | P1 - 10 | GPIO - 22 | P1 - 15 |

11. GPIO复位后的配置

复位后,大多数GPIO引脚默认配置为通用输入,但随着Raspbian Linux的更新和新Pi型号的推出,无法确定启动时的GPIO状态。因此,使用GPIO前应进行配置。

12. 上拉电阻

GPIO 2和3(I2C引脚)通过外部电阻连接到+3.3V电源,以满足I2C要求。其余GPIO引脚通过SoC内部的50kΩ电阻上拉或下拉。内部上拉电阻较弱,仅能为未连接的GPIO输入提供确定状态。对于外部电路,建议使用外部上拉电阻。

13. 配置上拉电阻

可在C程序中使用SoC寄存器GPPUP和GPPUDCLK0/1配置GPIO引脚的上拉电阻,具体步骤如下:
1. 在32位GPPUP寄存器的最右边2位写入所需的上拉配置:
- 00:禁用上拉控制
- 01:启用下拉控制
- 10:启用上拉控制
2. 等待150个周期,使上一步的写入生效。
3. 向要配置的32个GPIO引脚组中的每个GPIO位置写入1位。GPIOs 0 - 31由寄存器GPPUDCLK0配置。
4. 再等待150个周期,使步骤3生效。
5. 向GPPUP写入00,移除控制信号。
6. 再等待150个周期,使步骤5生效。
7. 最后,向GPPUDCLK0/1写入以移除时钟。

14. GPIO驱动强度

每个GPIO引脚的设计可安全地吸收或提供高达16 mA的电流,驱动强度可通过软件在2 - 16 mA之间配置。配置驱动强度的SoC寄存器如下表所示:
| 位 | 字段 | 描述 | I/O | 复位值 |
| — | — | — | — | — |
| 31:24 | PASSWRD | 写入时必须为0x5A | W | 0x00 |
| 23:05 | 保留 | 写入为零,读取忽略 | R/W |
| 04:04 | SLEW | 压摆率 | R/W | 0:压摆率受限;1:压摆率不受限 |
| 03:03 | HYST | 启用输入滞后 | R/W | 0:禁用;1:启用 |
| 02:00 | DRIVE | 驱动强度 | R/W | 0:2 mA;1:4 mA;2:6 mA;3:8 mA(默认,除28 - 45);4:10 mA;5:12 mA;6:14 mA;7:16 mA(GPIO 28 - 45) |

驱动强度并非电流限制,而是通过增加或减少放大器驱动来调整输出电压。对于轻负载,2 mA的驱动能力即可;对于高电流负载,则需增加驱动强度。

15. GPIO逻辑电平

树莓派的GPIO引脚使用3.3V逻辑电平,原始BCM2835 SoC的具体逻辑电平规格可能因新型号略有不同。

树莓派UART与GPIO硬件全解析

16. 驱动强度控制原理

为了更好地理解树莓派如何控制GPIO引脚的驱动强度,下面结合具体控制逻辑进行分析。树莓派通过控制 Drive0 Drive1 Drive2 这三条控制线路来调整驱动强度,具体逻辑如下:
- 当 Drive0 Drive1 Drive2 三条控制线路都为低电平(即都被禁用)时,只有底部的 2 mA 放大器处于激活状态。由于这个 2 mA 放大器对于所有输出引脚来说是始终启用的,所以此时代表的是最弱的驱动强度设置。
- 当 Drive0 被设置为高电平(即被启用)时,顶部的一个放大器会被激活,这个放大器能够额外提供 2 mA 的驱动电流。此时,总的驱动电流就从原本的 2 mA 增加到了 4 mA。
- 当 Drive1 被设置为高电平时,又会有一个额外的 4 mA 放大器被激活,这使得总的驱动电流进一步增加到了 8 mA。
- 当 Drive2 被设置为高电平时,会再激活一个放大器,从而使总的驱动能力达到最大的 16 mA。

下面用 mermaid 流程图来直观展示驱动强度的控制过程:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始]):::startend --> B{Drive0 = 0?}:::decision
    B -- 是 --> C(驱动强度 2 mA):::process
    B -- 否 --> D{Drive1 = 0?}:::decision
    D -- 是 --> E(驱动强度 4 mA):::process
    D -- 否 --> F{Drive2 = 0?}:::decision
    F -- 是 --> G(驱动强度 8 mA):::process
    F -- 否 --> H(驱动强度 16 mA):::process
    C --> I([结束]):::startend
    E --> I
    G --> I
    H --> I

需要注意的是,这些驱动能力的设置并不是电流限制器。它们的主要作用是根据负载的情况,通过调整放大器的驱动程度,来确保 GPIO 输出引脚的电压能够维持在合适的工作范围内。例如,当 GPIO 输出连接到像 CMOS 芯片或 MOSFET 晶体管这样的轻负载设备时,由于这些设备所需的电流非常小,所以最低的 2 mA 驱动强度通常就足够了。但如果 GPIO 输出连接的是一个需要较大电流的负载时,仅仅依靠 2 mA 的单缓冲器可能无法将输出的逻辑电平保持在规定的范围内。在这种情况下,就需要通过增加驱动强度,来使输出电压达到正确的工作范围。

17. 总结与实际应用建议

树莓派的 UART 和 GPIO 硬件在不同型号的发展过程中变得更加复杂,但也提供了更多的功能和灵活性。以下是根据前面内容总结的一些关键要点和实际应用建议:

17.1 UART 部分
  • 设备选择 :根据树莓派的型号和具体需求选择合适的 UART 设备。如果对数据完整性和功能要求较高,优先考虑 PL011 UART;如果对功能要求不高且需要将 PL011 用于其他用途(如蓝牙和 WIFI 支持),可以选择 Mini UART,但要注意其在高数据速率下可能出现的数据丢失问题。
  • 配置检查 :在使用 UART 前,通过查看 /boot/cmdline.txt /dev/serial0 等文件来确认使用的串行设备。如果需要将串行设备用于非控制台目的,记得使用 raspi-config 工具禁用串行控制台。
  • 硬件流控制 :如果需要使用硬件流控制 CTS 和 RTS 信号,将 GPIO 30 和 17 配置为备用功能 5。
17.2 GPIO 部分
  • 引脚配置 :使用 GPIO 前,务必对其进行配置,因为不同型号和系统版本的启动 GPIO 状态可能不同。
  • 上拉电阻 :对于 I2C 相关的 GPIO 2 和 3 引脚,依靠外部上拉电阻满足 I2C 要求;对于其他 GPIO 引脚,若外部电路需要上拉电阻,建议使用外部上拉电阻,而不是依赖内部较弱的 50 kΩ 电阻。
  • 驱动强度 :根据负载情况合理配置 GPIO 引脚的驱动强度。对于轻负载,选择 2 mA 的驱动强度;对于高电流负载,适当增加驱动强度,但要注意不超过每个引脚 16 mA 的安全电流。

通过合理利用树莓派的 UART 和 GPIO 硬件资源,并遵循上述建议,能够更好地发挥树莓派的性能,实现各种应用场景的需求。例如,在物联网项目中,可以利用 UART 进行数据传输,通过 GPIO 引脚连接各种传感器和执行器,实现数据的采集和控制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值