【无标题】树莓派 4B 多串口配置
0. 实验准备以及原理
 0.1 实验准备
 安装树莓派官方系统的树莓派 4B,有 python 环境,安装了 serial 库
 杜邦线若干
 屏幕或者可以使用 VNC 进入到树莓派的图形界面
0.2 原理
 树莓派 4B 有 UART0(PL011)、UART1(mini UART)和 4 个 PL011 串口共计有 6 个 UART
1. 硬件串口配置
 可以将硬件串口(例如 /dev/ttyAMA0)配置为普通的串口设备,以便与其他设备进行串口通信
确保树莓派的引脚上的串口功能没有被占用。默认情况下,树莓派的 GPIO 引脚会使用串口功能。可以通过编辑 /boot/config.txt 文件来禁用串口功能。在文件的末尾添加或修改以下行,保存文件后重启树莓派(可以使用vi来编辑此文件,vi 的使用可以查看这一篇文章):
enable_uart=1
 ?
enable_uart=1
在终端中运行以下命令可以确认驱动是否已经加载:
ls -l /dev/ttyAMA0
 1
 能看到下面的输出就代表驱动是正常的
默认情况下,树莓派会将 /dev/ttyAMA0 用作终端串口,而不是普通的串口设备。可以通过编辑 /boot/cmdline.txt 文件来禁用终端串口。找到以 console=serial0 开头的行,并将其修改为 console=tty1,如下图所示
 确保你的用户被添加到 dialout 组中,以便具有串口访问权限。运行以下命令将当前用户添加到 dialout 组:
sudo usermod -a -G dialout $USER
 1
 在添加到 dialout 组后,需要注销并重新登录才能使更改生效,到这里硬件串口就配置完成了,不需要看其他的可以直接跳到最后一节进行验证
2. 其他串口配置
 2.1 展示所有串口命令
 输出下面的命令可以看到所有的串口
dtoverlay -a | grep uart
 1
 2.2 查看特定串口信息
 使用下面的命令会展示串口的配置信息
dtoverlay -h uart3
 1
 2.3 配置开启串口 UART2-5
 在/boot/config.txt的末尾添加如下的代码,保存重启树莓派
dtoverlay=uart2
dtoverlay=uart3
dtoverlay=uart4
dtoverlay=uart5
查看是否生效
ls /dev/ttyAMA*
 1
 结果如下图
到这里就打开了所有的串口了
3. 验证结果
 各 UART 串口与 GPIO 对应关系:
GPIO14 = TXD0 -> ttyAMA0
 GPIO0 ?= TXD2 -> ttyAMA1
 GPIO4 ?= TXD3 -> ttyAMA2
 GPIO8 ?= TXD4 -> ttyAMA3
 GPIO12 = TXD5 -> ttyAMA4
GPIO15 = RXD0 -> ttyAMA0
 GPIO1 ?= RXD2 -> ttyAMA1
 GPIO5 ?= RXD3 -> ttyAMA2
 GPIO9 ?= RXD4 -> ttyAMA3
 GPIO13 = RXD5 -> ttyAMA4
 ?
GPIO14 = TXD0 -> ttyAMA0
GPIO0  = TXD2 -> ttyAMA1
GPIO4  = TXD3 -> ttyAMA2
GPIO8  = TXD4 -> ttyAMA3
GPIO12 = TXD5 -> ttyAMA4
GPIO15 = RXD0 -> ttyAMA0
GPIO1  = RXD2 -> ttyAMA1
GPIO5  = RXD3 -> ttyAMA2
GPIO9  = RXD4 -> ttyAMA3
GPIO13 = RXD5 -> ttyAMA4

这里进行两个验证:UART2的自环测试,UART2和3的串口间通信,以及一个究极测试:同时打开所有的串口(包括USB转的,看看树莓派的CPU使用率有多少)
3.1 UART2的自环测试
 杜邦线短接 GPIO4 和 GPIO5
 编写下面的 python 程序
import serial
ser1 = serial.Serial(port='/dev/ttyAMA2',baudrate=115200)
ser1.write(b'Hello, World!\n')
data = ser1.readline()
print(data)
 执行结果如下图
 3.2 UART2和3的串口间通信
 使用杜邦线按照下图的方式进行连接
GPIO4(TXD3)-------GPIO9(RXD2)
 GPIO5(RXD3)-------GPIO8(TXD2)
 1
 2
 然后编写如下的程序
import serial
ser2 = serial.Serial(port='/dev/ttyAMA2',baudrate=115200)
ser3 = serial.Serial(port='/dev/ttyAMA3',baudrate=115200)
ser2.write(b'hello ser3,I am ser2\n')
ser3.write(b'hello ser2,I am ser3\n')
line2 = ser2.readline()
line3 = ser3.readline()
print('ser2Rec:'+str(line2))
print('ser3Rec:'+str(line3))
 结果如下图,说明串口生效,实验成功:
 3.3 究极测试
 同时打开 USB0、USB1 和 ttyAMA0 到 ttyAMA4 一共 7 个串口,发送数据的同时存储数据,查看一下 CPU 的使用率
 我的配置为:
 USB0、1 使用 UART 转 TTL 模块,使用电脑发送数据过来
 ttyAMA0 作为硬件串口,然后改为的通用串口,也使用 UART 转 TTL 模块,电脑发送数据过来
 ttyAMA1 和 ttyAMA4 连接
 ttyAMA2 和 ttyAMA3 连接
 对应的连接图可以参考上面的GPIO对照着连线
 代码如下
import serial
import time
import threading
import sys
READ = 1
READTIME = 600
ser0 = serial.Serial(port='/dev/ttyAMA0',baudrate=115200)
ser1 = serial.Serial(port='/dev/ttyAMA1',baudrate=115200)
ser2 = serial.Serial(port='/dev/ttyAMA2',baudrate=115200)
ser3 = serial.Serial(port='/dev/ttyAMA3',baudrate=115200)
ser4 = serial.Serial(port='/dev/ttyAMA4',baudrate=115200)
serUSB0 = serial.Serial(port='/dev/ttyUSB0',baudrate=115200)
serUSB1 = serial.Serial(port='/dev/ttyUSB1',baudrate=115200)
def WriteSer1():
    global READ
    while(READ):
        ser1.write(b'I am ser1')
        
def WriteSer2():
    global READ
    while(READ):
        ser2.write(b'I am ser2')
        
def WriteSer3():
    global READ
    while(READ):
        ser3.write(b'I am ser3')
        
def WriteSer4():
    global READ
    while(READ):
        ser4.write(b'I am ser4')
        
def ReadSer0():
    ser0.write(bytearray([0xaa,0x0a]))
    global READ
    data0 = b''
    while(READ):
        if(ser0.in_waiting):
            data0 +=  ser0.read(ser0.in_waiting)
    f = open('ser0.bin','ab')
    f.write(data0)
    f.close()
    
def ReadSer1():
    global READ
    data1 = b''
    while(READ):
        if(ser1.in_waiting):
            data1 +=  ser1.read(ser1.in_waiting)
    f = open('ser1.bin','ab')
    f.write(data1)
    f.close()
    
def ReadSer2():
    global READ
    data2 = b''
    while(READ):
        if(ser2.in_waiting):
            data2 +=  ser2.read(ser2.in_waiting)
    f = open('ser2.bin','ab')
    f.write(data2)
    f.close()
def ReadSer3():
    global READ
    data3 = b''
    while(READ):
        if(ser3.in_waiting):
            data3 +=  ser3.read(ser3.in_waiting)
    f = open('ser3.bin','ab')
    f.write(data3)
    f.close()
    
def ReadSer4():
    global READ
    data4 = b''
    while(READ):
        if(ser4.in_waiting):
            data4 +=  ser4.read(ser4.in_waiting)
    f = open('ser4.bin','ab')
    f.write(data4)
    f.close()
    
def ReadSerUSB0():
    global READ
    dataUSB0 = b''
    while(READ):
        if(serUSB0.in_waiting):
            dataUSB0 +=  serUSB0.read(serUSB0.in_waiting)
    f = open('serUSB0.bin','ab')
    f.write(dataUSB0)
    f.close()
    
def ReadSerUSB1():
    global READ
    dataUSB1 = b''
    while(READ):
        if(serUSB1.in_waiting):
            dataUSB1 +=  serUSB1.read(serUSB1.in_waiting)
    f = open('serUSB1.bin','ab')
    f.write(dataUSB1)
    f.close()
#%%
def start():
    global READ
    timeStart = time.time()
    
    ser1Write_thread = threading.Thread(target=WriteSer1)
    ser2Write_thread = threading.Thread(target=WriteSer2)
    ser3Write_thread = threading.Thread(target=WriteSer3)
    ser4Write_thread = threading.Thread(target=WriteSer4)
    
    ser0_thread = threading.Thread(target=ReadSer0)
    ser1_thread = threading.Thread(target=ReadSer1)
    ser2_thread = threading.Thread(target=ReadSer2)
    ser3_thread = threading.Thread(target=ReadSer3)
    ser4_thread = threading.Thread(target=ReadSer4)
    serUSB0_thread = threading.Thread(target=ReadSerUSB0)
    serUSB1_thread = threading.Thread(target=ReadSerUSB1)
    
    ser1Write_thread.start()
    ser2Write_thread.start()
    ser3Write_thread.start()
    ser4Write_thread.start()
    
    ser0_thread.start()
    ser1_thread.start()
    ser2_thread.start()
    ser3_thread.start()
    ser4_thread.start()
    serUSB0_thread.start()
    serUSB1_thread.start()
    
    time.sleep(READTIME)
    READ = False
    print('test time'+str(time.time()-timeStart))
    sys.exit()
    
if __name__ == '__main__':
    start()
 ? ??
 使用命令,来查看当前CPU的使用率
htop
htop
 可以发现即使跑了这么多的串口,树莓派的 CPU 使用率依旧不算很高,4 核差不多都在 40% 的利用率左右
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!