[原创] 通过串口终端连接树莓派(CH340)

  • 背景:你是否遇到过"树莓派的WiFi连不上网络,有线连接树莓派也不具备条件"的情况?这个时候,你想通过终端连接到树莓派上还剩下哪些选择?串口就是其中一个可行的办法。对大多数人来说,这种连接方法都算比较少见,但它确实是一个在网络断链时的好方法。
  • 目标:让 macOS 通过 USB-TTL (CH340) 模块连接树莓派 GPIO 串口,获得一个完全不依赖网络的终端/登录通道(等同于 SSH 控制台,但走串口线)。
  • 树莓派版本:3B Rev 1.2

1. 先认识 CH340 模块:它是什么,能帮我们做什么

1.1 CH340 是什么

CH340 是一颗国产的"USB 转串口"芯片(这类芯片也常被叫做 USB-UART 桥接芯片)。市面上卖的那种USB-TTL 小板,核心就是这颗芯片,板上通常还会引出一排针脚,标着 VCC / 5V / 3V3 / TXD / RXD / GND

下面是我用AI绘制的CH340模块3D图:
CH340

下面是我的实拍图:
CH340

CH340
它做的事情可以一句话讲清楚:把你的电脑 USB 口变成一个"串口"。电脑这边看到的是一个串口设备,另一端(比如树莓派、单片机)看到的是标准的串口信号,CH340 负责在两者之间翻译数据。这样电脑就能通过串口协议和另一台设备互相收发数据了。

关于驱动

三个主流系统(Windows / macOS / Linux)都有 CH340 的驱动,多数情况下插上就能用,不需要手动装。

macOS 这边,驱动生效的标志是:系统里出现一个叫 /dev/cu.usbserial-XXX 的设备文件。你可以把它理解成"串口的门牌号"——终端程序(比如我们后面要用的 screen)就是靠打开这个文件来跟串口通信的。名字里的 XXX 是一串数字,每次插拔可能不一样。所以你插上 CH340 后,先执行下面这条命令确认一下设备在不在:

  • ounter(line
ls /dev/cu.usbserial*

能看到类似 /dev/cu.usbserial-110 的输出,就说明驱动没问题,可以继续往下走了。如果什么输出都没有,那多半是驱动没装好。
文章来源:https://www.codelast.com/

关于电平(电压标准)

串口信号的电平有两种常见标准:5V 和 3.3V。树莓派的 GPIO 是 3.3V 逻辑,所以接树莓派时要注意别让 5V 电平直接灌进 GPIO 引脚。CH340 小板一般 3.3V/5V 都兼容,本文的接法只用到 TXD、RXD、GND 三根线,不涉及供电脚,所以只要别把 5V 引脚接到树莓派上就行(后面 2 章会细说)。

1.2 用它连树莓派,具体能做什么

用途 说明
断网时的兜底登录 树莓派网络出问题(WiFi 连不上、网线也没条件)时,这是唯一还能进系统改配置、查日志的办法,也是本文的核心场景
看启动早期日志 GPIO 串口在系统启动很早期就能输出文字,内核启动卡住时靠它看看到底死在哪一步
给单片机下载/调试程序 Arduino、STM32、ESP32 这类板子常用串口烧录程序、打印调试信息
在没网络时传小文件 可以用 base64 之类的文本协议走串口慢慢传,9600 波特率下大约 0.8KB/s,只适合传很小的文件
接其他 TTL 串口外设 GPS 模块、蓝牙模块、需要 AT 指令的模块等,很多都是串口接口,可以共用这套接线思路
学习串口原理 串口是最基础的通信接口,折腾一遍能搞明白 tty、波特率、流控这些概念

1.3 为什么把它定位成"备用通道",而不是日常主力

  • 慢。9600 波特率换算下来每秒大约只有 0.8KB,敲命令、改配置够用,传文件会等到怀疑人生;
  • 电脑得用一根 USB 线物理连着树莓派附近,人不在旁边就用不了;
  • 日常调试当然还是 WiFi/网线 SSH 舒服,串口的意义在于:当网络这条路彻底断了,你还有一条路能进系统

2. 硬件准备与接线

2.1 需要准备的东西

部件 说明
CH340 USB-TTL 小板 网上很常见,板上一排针脚通常标着 5V、VCC、3V3、TXD、RXD、GND
杜邦线 母对母,准备 3~4 根
一台电脑(本文以 macOS 为例) 装好 CH340 驱动,插上后能看到/dev/cu.usbserial-XXX 设备

2.2 ⚠️ 接线规则:交叉 + 共地(最容易错的一步)

先解释一下串口的两根数据线:

  • TXD:发送(Transmit)——这根线负责"说";
  • RXD:接收(Receive)——这根线负责"听"。

通信要成立,必须一方的发送接到另一方的接收,也就是交叉接:

CH340 小板 树莓派 40-pin 排针
GND Pin 6 / 9 / 14 / 20 / 25 / 30 / 34 / 39(这些全是 GND,任选一个)
TXD(发送) Pin 10,也就是树莓派的 RXD / GPIO15
RXD(接收) Pin 8,也就是树莓派的 TXD / GPIO14
VCC / 3V3 / 5V 一律不接

三个容易踩的坑:

  1. TXD 和 RXD 必须交叉,绝不能 TXD 对 TXD。 如果接成 TXD 对 TXD,两边都在"说"、没人"听",结果就是完全收不到任何数据。记住这个画面:两个人都只对着对方说话、却都把耳朵捂上,谁也听不见谁。
  2. GND 必须共地。 意思是 CH340 的地线和树莓派的地线要连在一起,让两边有共同的电压参考点。如果不共地,表现是完全没有输出,或者收到一堆乱码(最常见的现象是收到 0 字节)。这一步看着不起眼,实际上一大半"没反应"的问题都出在它身上。
  3. 不要把 VCC / 3V3 / 5V 接到树莓派上。 树莓派自己有电源,CH340 小板靠 USB 口供电,两边电源脚对接会造成双电源冲突,严重时可能烧东西。

另外,杜邦线插拔多了容易接触不良。如果怀疑接触问题,换一根线、或者重新插紧往往就好了。
文章来源:https://www.codelast.com/

2.3 接线示意图

下面这张图把树莓派 40-pin 排针全部画出来了。排针是竖着排列的:左边一列是奇数号 1、3、5…,右边一列是偶数号 2、4、6…,从上往下递增。蓝色高亮的是我们真正用到的三个脚。

图中三个高亮触点分别是:

  • Pin 8:树莓派的 TXD(GPIO14)——接 CH340 的 RXD;
  • Pin 10:树莓派的 RXD(GPIO15)——接 CH340 的 TXD;
  • Pin 20:GND——图里选它只作示例,实际上树莓派上一堆 GND 脚(Pin 6/9/14/20/25/30/34/39)任选一个接都行。

再次强调:CH340 的 TXD 必须接树莓派的 RXD,CH340 的 RXD 必须接树莓派的 TXD,其他引脚一律不接。


3. 树莓派端要改的配置

要让树莓派通过 GPIO 串口提供登录服务,需要改三个系统文件。因为本文假设的场景是"树莓派已经没有任何网络连接",所以先讲怎么在没有网络的情况下修改这些文件,再逐个讲每个文件改什么。
文章来源:https://www.codelast.com/

3.1 没有网络时怎么改系统文件(拔卡方式)

先认识要改的三个文件:

文件 所在分区 作用
/boot/firmware/config.txt boot 分区(FAT32) 启用 GPIO 串口、决定用哪个 UART(3.2 节)
/boot/firmware/cmdline.txt boot 分区(FAT32) 让内核把启动日志输出到串口,并定好波特率(3.3 节)
/etc/systemd/system/serial-getty@*.service.d/override.conf 系统分区(ext4) 让系统在串口上启动登录程序(3.4 节)

这里有个背景知识需要先说明:树莓派的 SD 卡(TF 卡)其实分成两个分区。一个是 boot 分区,格式是 FAT32,里面放的是开机要用的配置文件(config.txtcmdline.txt 都在这里);另一个是 系统分区,格式是 ext4,装着整个操作系统。FAT32 分区在任何电脑上都能直接读写,而 ext4 分区普通电脑默认是看不到的。

拔卡修改的具体步骤:

  1. 关机断电:先在树莓派上正常关机,然后断开电源。切记不能带电拔卡,容易损坏文件系统;
  2. 取出 TF 卡,用读卡器插到电脑上;
  3. 改 boot 分区的文件:boot 分区是 FAT32,插上后电脑会直接识别。macOS 下它会自动挂载成一个盘,一般叫 /Volumes/bootfs,直接用文本编辑器打开里面的 config.txtcmdline.txt 修改保存就行;Windows、Linux 同理,打开 TF 卡对应的盘符/挂载点就能看到这两个文件;
  4. 系统分区里的文件:如果你需要改第三个文件(serial-getty 的 override),它在 ext4 系统分区里,普通电脑默认看不到。macOS 要用 debugfs 之类的 ext4 工具(需要 root 权限),Windows 可以用 ext2fsd 之类的软件。如果觉得这一步麻烦,可以先跳过它——先只改 boot 分区里的两个文件,等接上串口发现确实登录不了,再回头处理 3.4 节的问题;
  5. 安全弹出 TF 卡(macOS 里右键推出),插回树莓派,重新上电。

两个容易困惑的点,提前说明:

  • 路径差异:新版 Raspberry Pi OS(Debian 12/13)里,boot 分区在系统内挂在 /boot/firmware/;老版本是挂在 /boot/。但不管系统内路径怎么写,文件本身就在 boot 分区根目录里——你拔卡插电脑后,直接看盘符根目录下有没有 config.txt 就行,不用管 /boot/firmware 这种路径。
  • 全新卡 vs 用过的卡:如果你是刚烧录好系统、还没第一次开机的卡,也可以插电脑直接改 boot 分区,效果和改 /boot/firmware/ 一样;如果是已经用过的卡,改之前一定要先正常关机再拔。

3.2 启用 GPIO 串口,并决定用哪个 UART

树莓派 GPIO 上引出的串口默认是关闭的,需要在 /boot/firmware/config.txt 里打开它。用文本编辑器打开这个文件,在文件末尾追加:

  • ounter(line
enable_uart=1

光打开还不够,树莓派 3 上有个特殊情况需要决定:这颗芯片其实有两个串口硬件——一个叫 PL011(质量好、波特率准,但默认分配给蓝牙用),一个叫 mini-UART(功能弱一些、波特率会随 CPU 频率漂移)。GPIO 引出的串口到底用哪个,由要不要给蓝牙让路决定。有三个方案:

方案 config.txt 里的写法 结果
1. 关闭蓝牙,串口用最好的 PL011 dtoverlay=disable-bt GPIO 串口是/dev/ttyAMA0(PL011,波特率最准),但蓝牙彻底没了
2. 串口用 PL011、蓝牙挤到 mini-UART dtoverlay=miniuart-bt 理论可行,但在部分树莓派 3 上会导致蓝牙固件加载失败,不推荐
3. 什么都不加,维持默认 (不加 dtoverlay) 蓝牙正常用 PL011;GPIO 串口退而求其次用 mini-UART,即/dev/ttyS0

怎么选,取决于你要不要蓝牙:

  • 还要用蓝牙:选方案 3。GPIO 串口会是 /dev/serial0 -> ttyS0(mini-UART)。因为 mini-UART 的波特率会随 CPU 频率漂移,建议把波特率定在 9600 这种低速档,或者去固定 CPU 频率,否则可能出现乱码;
  • 不需要蓝牙,只想要最稳定的串口:选方案 1。GPIO 串口是 /dev/serial0 -> ttyAMA0(PL011),波特率精确,省心。

后面各小节的命令都以 方案 3(设备名 ttyS0 为例。如果你选了方案 1,把命令里出现的 ttyS0 全部换成 ttyAMA0 即可。

顺带一提:/dev/serial0 是一个软链接,它总是指向"当前 GPIO 串口实际对应的那个设备"(ttyS0ttyAMA0),所以不确定时先执行 ls -l /dev/serial0 看一眼它指向谁,心里就有数了。

3.3 让内核把启动信息输出到串口(顺便定波特率)

Linux 内核启动时的日志默认是输出到屏幕的。我们希望它同时也输出到 GPIO 串口,这样就算树莓派没接屏幕,也能从串口看到启动过程。

这个行为由 /boot/firmware/cmdline.txt 控制。用文本编辑器打开它,确认里面有这样一段(注意是 serial0,不是别的):

  • ounter(line
console=serial0,9600

serial0 就是 GPIO 串口的软链接名,9600 是波特率。如果文件里同时有 console=tty1 之类的(那是输出到本地屏幕的),不要删掉它们,只把 serial0 这一段波特率定为 9600 就好。

波特率这个东西,后面会反复强调:发送端和接收端必须用同一个波特率,否则收到的就是乱码。

3.4 让系统在串口上启动登录程序(serial-getty)

前面两步只是让内核往串口输出日志,但光有日志还不能登录。要登录,系统里得有一个程序在串口上等着,显示 login: 提示符、接受你输入用户名密码——这个程序叫 getty,对应的系统服务是 serial-getty@<串口设备>.service

树莓派系统在检测到 GPIO 串口启用后,一般会自动启动对应的 serial-getty 服务。但有一个很常见的坑:getty 的波特率必须和内核 console 的波特率一致(都是 9600)。如果登录提示符不出现,多半就是 getty 没启动,或者波特率不对。

手动确认/修正的方法是给 getty 写一个配置文件,强制指定设备和波特率。在树莓派上创建 /etc/systemd/system/serial-getty@ttyS0.service.d/override.conf(目录可能要自己建):

  • ounter(line
  • ounter(line
  • ounter(line
[Service]ExecStart=ExecStart=-/sbin/agetty --noclear --keep-baud ttyS0 9600 vt100

如果你的 GPIO 串口实际是 ttyAMA0(方案 1),就把上面两处 ttyS0 换成 ttyAMA0,文件名也跟着改成 serial-getty@ttyAMA0.service.d/override.conf

然后重新加载 systemd 并启用服务:

  • ounter(line
  • ounter(line
sudo systemctl daemon-reloadsudo systemctl enable --now serial-getty@ttyS0.service

验证服务确实在跑:

  • ounter(line
  • ounter(line
systemctl is-active serial-getty@ttyS0   # 应该输出 activesystemctl list-units | grep ttyS0        # 能看到 serial-getty 在运行

到这里,树莓派端的配置就齐了:GPIO 串口已启用、内核往串口输出日志、getty 在串口上等你登录。


4. macOS 这一端怎么连

4.1 先确认设备名

CH340 插上后 macOS 会自动给它分配一个设备文件,名字是 /dev/cu.usbserial-XXXX(也可能是 /dev/tty.usbserial-XXXX)。注意末尾那串数字每次重新插拔都可能变(比如这次是 11310,下次变成 11320,再下次是 110),所以别死记一个名字,每次用之前先查一下:

  • ounter(line
ls /dev/cu.usbserial*

如果这条命令什么都查不到,说明驱动没装好,去 WCH 官网装 macOS 驱动。

4.2 用 screen 连上去

macOS 自带的 screen 命令就能当串口终端用:

  • ounter(line
screen /dev/cu.usbserial-110 9600

格式是 screen 设备文件 波特率,把设备名换成你上一步查到的实际名字。连接成功后,按一下回车,应该能看到:

  • ounter(line
rpi login:

输入树莓派的用户名和密码,就进入 shell 了,用法和 SSH 完全一样。

退出 screen 的方法:先按 Ctrl+A,松开后再按 K,最后按 y 确认退出。

4.3 不想开终端?也可以用命令直接收发

如果你是脚本/程序要自动化测试串口,不需要交互式终端,可以用下面的方式非交互地验证:

  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
DEV=/dev/cu.usbserial-110                       # 换成你实际的设备名stty -f "$DEV" 9600 raw -echo                   # 设置波特率 9600,关闭回显(timeout 4 cat "$DEV" > /tmp/rx.txt &)          # 后台启动一个读取,读 4 秒printf '\r' > "$DEV"                            # 往串口写一个回车,触发登录提示cat /tmp/rx.txt                                 # 查看收到的内容,应该能看到 "rpi login:"

stty 负责配置串口参数,cat 负责读,printf 负责写——把串口当成一个文件来读写就行。


5. 调试记录:踩过的坑

下面这些是实际接线、调通过程中遇到的问题。如果你一次就成功了,可以跳过本章;如果哪里不对,按顺序排查通常能解决。
文章来源:https://www.codelast.com/

5.1 第一次接上:完全没有输出,或者全是乱码

刚接上时最常见的两个现象:读串口读到 0 字节(什么都没有),或者读到 40~70 字节的乱码。

按下面的顺序排查:

第 1 步:先确认 CH340 小板本身是好的(环回测试)

把 CH340 和树莓派的接线全部断开,然后用一根杜邦线把 CH340 板上的 TXD 和 RXD 短接(直接连在一起)。这样一来,CH340 自己发出去的数据会原路回到自己。然后用 screen 连上串口随便敲几个字:如果敲什么回显什么,说明 CH340 小板、USB 线、驱动这一整条链路都是好的,问题出在树莓派那一侧。

不想开终端的话,也可以用命令自动验证:

  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
stty -f $DEV 115200 raw -echo(timeout 8 cat $DEV > /tmp/loop.txt &)   # 后台读printf 'HELLO_LOOP' > $DEV                # 写入一串测试文字grep HELLO_LOOP /tmp/loop.txt && echo OK   # 能在读到的内容里找到它 => 模块正常

如果这步通过,说明小板没问题,继续看第 2 步。

第 2 步:检查 GND 是否共地、TXD/RXD 是否交叉

读到的字节数是 0 时,优先怀疑两件事:GND 没接(换一个 GND 引脚试试),或者 TXD/RXD 没交叉。我实际遇到过:把 GND 从 Pin 30 换到 Pin 20 之后,读到的数据从 0 字节一下子变成 182 字节——共地的影响就是这么明显。

第 3 步:把 TXD 和 RXD 两根线对调

如果前面都查过还是没数据,把 TXD、RXD 两根线互换位置再试。很多时候数据从无到有,就差这一下。

5.2 有数据了,但是全是乱码 → 波特率不对

现象:能收到数据了,但内容完全没法看,全是乱码;而且换了好几档波特率读出来的都是"长度差不多的乱码"。

这是因为两边的波特率不一致。串口通信里,发送方和接收方必须用同样的波特率(相当于约定同样的说话语速),否则对方听到的就是无意义的声音。

推荐用"矩阵测试"来找到正确的波特率:树莓派和 macOS 两边同步切到同一个波特率,树莓派持续发一段特征文字,macOS 在另一边读,看哪一档能读出可读的文本。

树莓派侧(示例用 9600):

  • ounter(line
  • ounter(line
sudo stty -F /dev/ttyS0 9600 raw -echo        # ttyS0 或 ttyAMA0,按你实际设备名for i in 1 2 3 4; do echo -n "MATRIX_BAUD_9600_$i" > /dev/ttyS0; sleep 0.2; done

macOS 侧:

  • ounter(line
  • ounter(line
  • ounter(line
stty -f $DEV 9600 raw -echo(timeout 4 cat $DEV > /tmp/mx.txt &)grep MATRIX_BAUD /tmp/mx.txt && echo 通过

我实际测试的结果是:9600 波特率下两边完全互通,反而 115200 读出来是乱的——这块 CH340 小板在 115200 这个高速档上精度不稳。所以最后统一把波特率定在 9600(8 数据位、无校验、1 停止位,也就是常说的 8N1),内核 console、getty、macOS 端全部用 9600。

5.3 能看到内核日志,但没有 login 提示 → getty 没起来

现象:串口上能看到内核启动的日志,但日志播完就没了,一直没有 login: 提示符。

这说明问题不在硬件,而在系统这边——没有程序在串口上等你登录,也就是 3.4 节说的 getty 没有正确启动,或者它的波特率和 console 不一致。解决办法就是按 3.4 节写好 override 文件、启用对应的 serial-getty@<设备>.service

5.4 换了个 USB 口,就连不上了 → 设备名变了

现象:之前明明连得好好的,换了个 USB 口再插,screen 报错 [screen is terminating]

原因在 4.1 节说过:设备名末尾的数字每次插拔都可能变。换了 USB 口,旧名字就失效了。解决办法很简单:重新执行 ls /dev/cu.usbserial* 查出新的设备名,用新名字重新连接。


6. 最终验证(确认可用)

配置全部完成后,用下面两条验证整个链路是通的。
文章来源:https://www.codelast.com/

交互式验证(macOS 终端里):

  • ounter(line
  • ounter(line
screen /dev/cu.usbserial-110 9600# 应该看到 rpi login:,输入用户名密码进入 shell

非交互式验证(脚本里用):

  • ounter(line
  • ounter(line
printf '\r' > $DEVtimeout 5 cat $DEV        # 应该能看到 "rpi login:"

文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤ 
转载需注明出处:codelast.com 
感谢关注我的微信公众号(微信扫一扫):
wechat qrcode of codelast
以及我的微信视频号:

发表评论