1. 树莓派串口通信基础认知

第一次接触树莓派串口时,我也被那些ttyAMA0、ttyS0之类的术语搞得晕头转向。简单来说,树莓派就像个自带双卡双待的手机——它有两套串口系统:硬件串口(/dev/ttyAMA0)和mini串口(/dev/ttyS0)。硬件串口相当于VIP通道,有独立的时钟源保证通信质量;而mini串口就像普通通道,性能完全取决于CPU的忙碌程度。

在树莓派4B上,这两个串口还有个身份标签:serial0和serial1。默认情况下,硬件串口被分配给蓝牙模块使用(serial1),而GPIO引脚上的串口功能(8号TX/10号RX)使用的是性能较差的mini串口(serial0)。这就好比把家里的主卧让给了蓝牙这个"客人",自己却挤在次卧里。

实际开发中最让人头疼的是,当你用ls /dev查看设备时,可能会发现ttyAMA0和ttyS0的位置经常"互换"。这不是系统bug,而是映射关系发生了变化。我曾在项目截止前熬夜排查这个问题,后来才明白需要通过修改/boot/config.txt来重新分配串口资源。

2. 硬件串口配置实战

2.1 释放被占用的硬件串口

要让硬件串口为我们所用,首先得让蓝牙模块"搬家"。最稳妥的方法是使用raspi-config工具:

sudo raspi-config

依次选择:

  1. Interfacing Options
  2. Serial
  3. 关闭串口登录功能(选择No)
  4. 打开硬件串口(选择Yes)

这个操作相当于把串口从系统控制权中解放出来。记得我第一次操作时,不小心勾选了Serial Console选项,结果导致串口被终端占用,通信始终不成功。重启后通过ls -l /dev/serial*查看,正确的映射应该是serial0 -> ttyAMA0。

2.2 修改启动配置文件

接下来编辑/boot/config.txt文件,这是树莓派的"启动清单":

sudo nano /boot/config.txt

在文件末尾添加两行关键配置:

dtoverlay=pi3-miniuart-bt
force_turbo=1

第一行告诉系统:把mini串口分配给蓝牙,释放硬件串口;第二行则是保证时钟稳定性。保存后千万别忘了sudo reboot重启,我有次改了十几遍配置都不生效,最后发现是忘了重启。

2.3 验证串口映射

重启后,用这个命令检查成果:

ls -l /dev/serial*

理想状态下应该看到:

serial0 -> ttyAMA0
serial1 -> ttyS0

如果显示相反,说明配置没生效。这时可以检查config.txt是否保存成功,或者尝试在dtoverlay那行后面加上swap_uart=1参数。

3. Minicom安装与配置

3.1 安装串口调试神器

Minicom相当于Linux界的串口助手,安装只需一条命令:

sudo apt-get install minicom

但新手常会遇到找不到软件包的问题,这通常是因为没更新软件源。建议先执行:

sudo apt-get update

3.2 首次运行配置

直接运行minicom -s进入配置菜单,重点设置:

  1. Serial port setup
  2. 选择正确的设备(通常是/dev/ttyAMA0)
  3. 波特率按需设置(9600或115200)
  4. 关闭硬件流控(Hardware Flow Control设为No)

保存为默认配置后,以后就可以直接用minicom命令启动了。我习惯用这个组合命令:

minicom -D /dev/ttyAMA0 -b 115200

其中-D指定设备,-b设置波特率。注意波特率要和通信设备一致,否则会收到乱码。

3.3 实用操作技巧

Minicom有几个隐藏快捷键:

  • Ctrl+A → Z:调出帮助菜单
  • Ctrl+A → Q:完全退出
  • Ctrl+A → C:清屏
  • Ctrl+A → E:切换本地回显

有次调试时我疯狂输入却看不到任何反馈,差点以为硬件坏了,后来才发现是误关了回显功能。另外,minicom默认不会显示自己发送的数据,可以通过配置开启"本地回显"。

4. 完整通信测试流程

4.1 硬件连接指南

准备USB转TTL模块(如CH340),连接方式:

  • 树莓派8号引脚(TX) → TTL模块RX
  • 树莓派10号引脚(RX) → TTL模块TX
  • 任意GND引脚 → TTL模块GND

注意千万别接反TX/RX,否则数据无法传输。我曾在紧急调试时不小心接反,排查了半小时才发现这个低级错误。

4.2 双向通信测试

在树莓派启动minicom,在PC端打开串口助手(如Putty或Arduino IDE的串口监视器)。双方设置相同波特率后:

  1. 在PC端发送"Hello Raspberry"
  2. 树莓派端应立即显示接收到的内容
  3. 在minicom中输入回复信息
  4. PC端应能正确接收

如果只有单向通信正常,检查接线是否松动;如果全是乱码,确认波特率设置;如果完全没反应,可能需要检查串口映射是否正确。

4.3 常见问题排查

症状1:提示"Device /dev/ttyAMA0 is locked" 解决方法:

sudo rm /var/lock/LCK..ttyAMA0

症状2:Permission denied 需要将用户加入dialout组:

sudo usermod -a -G dialout $USER

然后注销重新登录

症状3:发送数据导致系统卡死 可能是流控冲突,在minicom配置中关闭硬件流控,或者在config.txt添加:

enable_uart=1

5. 进阶应用与编程控制

5.1 Python串口编程

安装pyserial库:

pip install pyserial

简单测试脚本:

import serial
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
try:
    while True:
        if ser.in_waiting > 0:
            data = ser.readline().decode('utf-8').rstrip()
            print(f"Received: {data}")
            ser.write(f"Echo: {data}\n".encode())
except KeyboardInterrupt:
    ser.close()

5.2 C语言WiringPi方案

先安装开发库:

sudo apt-get install wiringpi

示例代码:

#include <wiringSerial.h>
int main() {
    int fd = serialOpen("/dev/ttyAMA0", 9600);
    while(1) {
        if(serialDataAvail(fd)) {
            char c = serialGetchar(fd);
            serialPutchar(fd, c); // 回传字符
        }
    }
    serialClose(fd);
    return 0;
}

编译命令:

gcc serial_test.c -o test -lwiringPi

5.3 系统服务自启动

创建/etc/rc.local启动脚本:

#!/bin/bash
minicom -D /dev/ttyAMA0 -b 9600 -S script.txt &
exit 0

其中script.txt包含自动执行的AT命令等。记得给rc.local加执行权限:

sudo chmod +x /etc/rc.local

在完成所有配置后,建议用绝缘胶带固定杜邦线连接处。我有次演示项目时因为线材松动,现场调试了20分钟才恢复正常通信。现在我的树莓派上都用热熔胶做了简单固定,再没出现过接触不良的问题。

更多推荐