跳到主要内容

串口通讯

通用异步收发器(Universal Asynchronous Receiver/Transmitter),简称UART,是一种串行、异步、全双工的通信协议,在嵌入式领域应用的非常广泛,如下为20pin扩展接口的串口部分,在使能时需要注意复用的影响。本章节以串口UART5_TX_M0/UART5_RX_M0为例,验证串口通讯部分。

Net nameNUMNUMNet name
UART6_RX_M1GPIO1_A0_3V312GPIO4_D5_3V3UART5_TX_M0
UART6_TX_M1GPIO1_A1_3V334GPIO4_D4_3V3UART5_RX_M0
UART6_RTSN_M1GPIO1_A2_3V356GPIO4_D3_3V3UART5_RTSN_M0
UART6_CTSN_M1GPIO1_A3_3V378GPIO4_D2_3V3UART5_CTSN_M0
UART7_RX_M2GPIO1_B4_3V3910GPIO1_C6_1V8UART0_RTSN
GND1112GND
UART4_TX_M2GPIO1_B3_3V31314SARADC_VIN21V8 SARADC in
UART4_RX_M2GPIO1_B2_3V31516VCC3V3_SYS
GPIO1_B1_3V31718VCC12V_DCIN
VCC5V0_SYS1920VCC12V_DCIN

DTS修改与编译

# 修改rk3588-toybrick-x0.dtsi文件
&uart5 {
status = "okay";
pinctrl-0 = <&uart5m0_xfer &uart5m0_ctsn>;
};

重新编译kernel(./edge build -k)并更新烧录boot_linux.img至开发板,通过命令 ls /dev/ttyS*可以查看到ttyS5设备(即为UART5_M0)

RK3588_ttyS_1 </left>

串口链接

通过串口线或USB转串口线,把开发板与电脑连接起来:

  • 开发板 ------ 电脑
  • TXD ------ RXD
  • RXD ------ TXD
  • GND ----- GND

串口相关命令

# 查询其通信参数命令
stty -F /dev/ttyS5

# 设置通讯速率,其中 ispeed 为输入速率, ospeed 为输出速率
stty -F /dev/ttyS5 ispeed 115200 ospeed 115200

# 默认串口是开启回显的可以使用以下命令关闭回显
stty -F /dev/ttyS5 -echo

# 关闭RTS/CTS流控
stty -F /dev/ttyS5 -crtscts

Windows主机通讯

配置好串口调试助手后,尝试使用如下命令测试发送/读取数据

# 使用 echo 命令向终端设备文件写入字符串
echo Hello! > /dev/ttyS5
echo "Toybrick funny" > /dev/ttyS5

# 使用 cat 命令读取终端设备文件
cat /dev/ttyS5

执行结果

RK3588_ttyS_2

设备测试用例

以下是使用Python进行串口通信的示例代码:

import serial
import time
import sys

class UARTTest:
def __init__(self, port="/dev/ttyS5", baudrate=115200):
self.ser = serial.Serial(
port=port,
baudrate=baudrate,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)

def send_command(self, cmd):
"""发送命令到串口"""
self.ser.write(cmd.encode() + b'\n')
time.sleep(0.1) # 等待数据发送完成

def receive_data(self):
"""从串口接收数据"""
if self.ser.in_waiting:
return self.ser.readline().decode().strip()
return None

def transfer_file(self, filename, is_send=True):
"""传输文件
is_send=True: 发送文件
is_send=False: 接收文件
"""
if is_send:
with open(filename, 'rb') as f:
data = f.read()
self.ser.write(data)
else:
with open(filename, 'wb') as f:
while True:
if self.ser.in_waiting:
data = self.ser.read(self.ser.in_waiting)
if not data:
break
f.write(data)

def close(self):
"""关闭串口"""
self.ser.close()

# 使用示例
if __name__ == "__main__":
uart = UARTTest()

# 发送命令示例
uart.send_command("Hello RK3588!")

# 接收数据示例
while True:
data = uart.receive_data()
if data:
print(f"Received: {data}")

# 文件传输示例
# uart.transfer_file("test.txt", True) # 发送文件
# uart.transfer_file("received.txt", False) # 接收文件

uart.close()

使用前需要安装pyserial库:

pip3 install pyserial
备注

在运行程序前,请确保已经正确配置了串口权限,可能需要使用sudo运行或将当前用户添加到dialout组:

sudo usermod -a -G dialout $USER