3. UART通讯

本章中,我们开始为大家介绍一种常见的通讯协议UART, 在我们的鲁班猫板卡上,我们常常使用终端来与板卡进行交互, 而这个终端与板卡连接的众多方式之中,UART串口就是我们最常使用的方式之一。

关于UART协议的具体内容,我们在此不作过多探究,大家可以自行搜索UART通讯协议的相关知识学习。

本章中,我们的重点是使用前面Python库,来调用板卡上的串口资源。硬件上,通过板卡与USB转TTL模块连接到我们的电脑上, 并通过串口上位机来进行实验现象的演示和操作。

重要

若无特殊提及,本书教程基于Python 3.8.10版本(extboot分区Ubuntu20.04镜像)进行实验及讲解。

3.1. 实验准备

3.1.1. 添加UART资源

在板卡上的部分GPIO可能没有启用,可注释掉某些设备树节点或者设备树插件的加载,重启系统来开启, LubanCat_RK系列板卡的引脚参考下: 《LubanCat-RK系列-40pin引脚对照图》

如笔者使用的鲁班猫LubanCat 2板卡,根据引出的40个引脚对照图,串口资源可以使用UART3,下面我们开启下UART3的设备树插件:

# 不同板卡的配置文件和pwm不同,以LubanCat 2为例,配置文件为uEnvLubanCat 2.txt,
# 使用下面命令:
sudo vim /boot/uEnv/uEnvLubanCat 2.txt
#进入编辑模式,取消pwm前面的注释,保存并退出文件,重启系统
broken

如果使用的是其他鲁班猫RK系列板卡,也是类似操作。

# 在终端中输入如下命令,可以查看到UART资源:
ls /dev/ttyS*

板卡上的UART资源示例,仅供参考:

broken

其中/dev/ttyS3对应的就是板卡上的uart3资源。

3.1.2. 硬件连接

注:硬件连接小节,需要大家根据自身开发环境等情况对本章内容进行参考调整。

本章中,我们通过上述Python库,编写使用LubanCat 2板卡上UART3资源的代码, 并通过USB转TTL模块、串口上位机来进行代码正确性测试。

笔者硬件连接如图,仅供参考:

broken

USB转TTL模块连接如上图示。

3.2. 方式一:使用pyserial库

pyserial 库封装了对串口资源的访问方法,该库兼容多种平台对串口资源使用, 有许多平台特性相关的方法,官方的使用说明参考:pyserial 库代替。

在Linux系统上,关于UART子系统相关内容,参考 《串口通讯》

3.2.1. 安装pyserial

重要

在前面小节的实验中,可能已经安装了此库,如已安装则跳过此操作。

pyserial 的安装方式如下:

# 在板卡使用如下命令安装
sudo pip3 install pyserial

3.2.2. 使用pyserial

配套代码 io/uart/uart_test0.py文件内容
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
""" pyserial uart 测试 """
import serial

# 打开uart3,设置串口波特率为115200,数据位为8,无校验位,停止位为1,不使用流控制,以非阻塞模式打开串口,等待时间为3s
with serial.Serial(
    "/dev/ttyS3",
    baudrate=115200,
    bytesize=serial.EIGHTBITS,
    stopbits=serial.STOPBITS_ONE,
    parity=serial.PARITY_NONE,
    timeout=3,
) as uart3:
    # 使用申请的串口发送字节流数据 "Hello World!\n"
    uart3.write(b"Hello World!\n")

    # 以非阻塞的方式打开的串口,在读取串口接收的数据时,该函数返回条件二者满足其一,一、读取到128个字节,二、读取时间超过1秒
    buf = uart3.read(128)

    # 注:Python读取出来的数据类型为:bytes
    # 打印原始数据
    print("原始数据:\n", buf)
    # 转码为gbk字符串,可以显示中文
    data_strings = buf.decode("gbk")
    # 打印读取的数据量及数据内容
    print("读取到 {:d} 个字节 , 以字符串形式打印:\n {:s}".format(len(buf), data_strings))

3.2.2.1. 实验操作

由于在硬件连接时,已经将uart3对应的TX\RX接口与USB转TTL模块的RXD\TXD接口连接, 所以要查看实验现象,需要使用到串口上位机以显示数据方便观察实验现象。

使用野火多功能调试助手中,就自带串口上位机。

broken

如图,我们在串口助手中设置串口的工作模式与我们程序配置的一致,并打开对应的端口, 即图中的1、2步骤。接下我们运行程序。

示例代码使用LubanCat i.MX6ULL MINI板卡,操作如下:

# 确认已安装pyserial包
# 确认使能了UART设备树插件

# 在板卡uart_test.py所在的目录执行如下命令
sudo python3 uart_test.py

# 可看到串口助手打印出的程序中编程好的数据:Hello World!\n

在终端中输入命令后,我们在串口助手中编辑要发送的数据,并发送,即图中的3、4步骤。

在等待超时后,可看到终端打印出的接收到的数据:你好世界

broken

关于该库,更多的用法,参见:pyserial API

3.3. 方式二:使用python-periphery

python-periphery 库支持的UART功能是基于Linux的UART系统实现的,所以要想利用该库使用到UART的功能, 需要板卡提供支持。像鲁班猫板卡,就可以完美使用 python-periphery 库UART通讯功能。

3.3.1. 安装 python-periphery

重要

如在前面小节中安装了此库,务必跳过此操作。

python-periphery 的安装方式如下:

# 在板卡使用如下命令安装
sudo pip3 install python-periphery

3.3.2. periphery使用UART功能

使用 python-periphery 库进行UART功能使用的示例代码如下:

配套代码 io/uart/uart_test1.py文件内容
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
""" python-periphery uart 测试 """
from periphery import Serial

try:
    # 申请串口资源/dev/ttyS3,设置串口波特率为115200,数据位为8,无校验位,停止位为1,不使用流控制
    serial = Serial(
        "/dev/ttyS3",
        baudrate=115200,
        databits=8,
        parity="none",
        stopbits=1,
        xonxoff=False,
        rtscts=False,
    )
    # 使用申请的串口发送字节流数据 "python-periphery!\n"
    serial.write(b"python-periphery!\n")

    # 读取串口接收的数据,该函数返回条件二者满足其一,一、读取到128个字节,二、读取时间超过1秒
    buf = serial.read(128, 1)

    # 注:Python读取出来的数据类型为:bytes
    # 打印原始数据
    print("接收的原始数据:\n", buf)

    # 转码为gbk字符串,可以显示中文
    data_strings = buf.decode("gbk")

    # 打印读取的数据量及数据内容
    print("读取到 {:d} 个字节 , 以字符串形式打印:\n {:s}".format(len(buf), data_strings))
finally:
    # 释放申请的串口资源
    serial.close()

代码说明:

  • 第6行,申请UART资源,占用uart3,配置对应的工作模式

  • 第16行,使用申请到的串口资源发送数据

  • 第19行,使用申请到的串口资源接收数据,接收方式为阻塞接收

  • 第23~29行,将读取到的数据打印出来

  • 第32行,释放UART资源,释放uart3

3.3.2.1. 实验操作

实验操作与上同。

示例代码使用LubanCat 2板卡,操作如下:

# 确认已安装python-periphery包
# 确认使能了UART设备树插件

# 在板卡uart_test.py所在的目录执行如下命令
sudo python3 uart_test1.py

# 可看到串口助手打印出的程序中编程好的数据:Hello World!\n

在终端中输入命令后,我们在串口助手中编辑要发送的数据,并发送,即图中的3、4步骤。

在等待超时后,可看到终端打印出的接收到的数据:你好

broken

自此,实验完成。

关于 python-periphery 库更多的UART用法,关注下: Periphery UART