树莓派3:64位系统串口(UART)使用问题的解决方法

devtools/2024/11/28 22:49:18/

前言

当我们要使用串口进行zigbee的短距离通信时,发现无法使用串口.

原因

树莓派3bCPU内部有两个串口,一个硬件串口(就是我们平时使用的UART),还有一个迷你串口(mini-uart),在老版本的树莓派中把硬件串口分配在GPIO上,可以单独使用.但是在新的树莓派中官方把硬件串口给了蓝牙模块上,而将一个没有时钟源,必须使用内核提供时钟参考源的mini串口,分发给GPIO的串口,这样以来由于内核的频率本身是在一直变换的,导致"mini串口"的速率不稳定,出现不能使用的情况.(我这边甚至没有显示出来(就是没有/dev/serial0 ->ttyS0)),工程师也知道这个bug了就没直接启动mini串口,只准我们用蓝牙.

解决只有serial1 -> ttyAMA0的情况

这是没打开GPIO串口的情况,只有serial1(蓝牙)使用的是ttyAMA0(硬件串口):

这里我试了很多方法,大体分为两种:
1,sudo  nano  /boot/config.txt 去里面打开写enable_uart=1,或者其他这就要看(cd /boot/overlays/#提供了README)这个文件的README了.
下面就是README的全部有关UART的解释

  krnbt_baudrate          Set the baudrate of the PL011 UART when usedwith krnbt=onuart0                   Set to "off" to disable uart0 (default "on")uart1                   Set to "on" or "off" to enable or disable uart1(default varies)
Name:   disable-bt
Info:   Disable onboard Bluetooth on Pi 3B, 3B+, 3A+, 4B and Zero W, restoringUART0/ttyAMA0 over GPIOs 14 & 15.N.B. To disable the systemd service that initialises the modem so itdoesn't use the UART, use 'sudo systemctl disable hciuart'.
Load:   dtoverlay=disable-bt
Params: <None>Name:   dpi18
Info:   Overlay for a generic 18-bit DPI displayThis uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output2-3 seconds after the kernel has started.
Load:   dtoverlay=dpi18
Params: <None>Name:   dpi18cpadhi
Info:   Overlay for a generic 18-bit DPI display (in 'mode 6' connection scheme)This uses GPIOs 0-9,12-17,20-25 (so no I2C, uart etc.), and activatesthe output 3-3 seconds after the kernel has started.
Load:   dtoverlay=dpi18cpadhi
Params: <None>Name:   dpi24
Info:   Overlay for a generic 24-bit DPI displayThis uses GPIOs 0-27 (so no I2C, uart etc.), and activates the output2-3 seconds after the kernel has started.
Load:   dtoverlay=dpi24
Params: <None>Name:   midi-uart0
Info:   Configures UART0 (ttyAMA0) so that a requested 38.4kbaud actually gets31.25kbaud, the frequency required for MIDI
Load:   dtoverlay=midi-uart0
Params: <None>Name:   midi-uart1
Info:   Configures UART1 (ttyS0) so that a requested 38.4kbaud actually gets31.25kbaud, the frequency required for MIDI
Load:   dtoverlay=midi-uart1
Params: <None>Name:   midi-uart2
Info:   Configures UART2 (ttyAMA1) so that a requested 38.4kbaud actually gets31.25kbaud, the frequency required for MIDI
Load:   dtoverlay=midi-uart2
Params: <None>Name:   midi-uart3
Info:   Configures UART3 (ttyAMA2) so that a requested 38.4kbaud actually gets31.25kbaud, the frequency required for MIDI
Load:   dtoverlay=midi-uart3
Params: <None>Name:   midi-uart4
Info:   Configures UART4 (ttyAMA3) so that a requested 38.4kbaud actually gets31.25kbaud, the frequency required for MIDI
Load:   dtoverlay=midi-uart4
Params: <None>Name:   midi-uart5
Info:   Configures UART5 (ttyAMA4) so that a requested 38.4kbaud actually gets31.25kbaud, the frequency required for MIDI
Load:   dtoverlay=midi-uart5
Params: <None>Name:   miniuart-bt
Info:   Switch the onboard Bluetooth function on Pi 3B, 3B+, 3A+, 4B and Zero Wto use the mini-UART (ttyS0) and restore UART0/ttyAMA0 over GPIOs 14 &15. Note that this may reduce the maximum usable baudrate.N.B. It is also necessary to edit /lib/systemd/system/hciuart.serviceand replace ttyAMA0 with ttyS0, unless using Raspbian or anotherdistribution with udev rules that create /dev/serial0 and /dev/serial1,in which case use /dev/serial1 instead because it will always becorrect. Furthermore, you must also set core_freq and core_freq_min tothe same value in config.txt or the miniuart will not work.
Load:   dtoverlay=miniuart-bt,<param>=<val>
Params: krnbt                   Set to "on" to enable autoprobing of Bluetoothdriver without need of hciattach/btattachName:   pi3-miniuart-bt
Info:   This overlay has been renamed miniuart-bt, keeping pi3-miniuart-bt asan alias for backwards compatibility.
Load:   <Deprecated>Name:   qca7000-uart0
Info:   in-tech's Evaluation Board for PLC Stamp micro (UART)This uses uart0/ttyAMA0 over GPIOs 14 & 15 to connect the QCA7000.But it requires disabling of onboard Bluetooth onPi 3B, 3B+, 3A+, 4B and Zero W.
Load:   dtoverlay=qca7000-uart0,<param>=<val>
Params: baudrate                Set the baudrate for the UART (default"115200")Name:   sc16is750-i2c
Info:   Overlay for the NXP SC16IS750 UART with I2C InterfaceEnables the chip on I2C1 at 0x48 (or the "addr" parameter value). Toselect another address, please refer to table 10 in reference manual.
Load:   dtoverlay=sc16is750-i2c,<param>=<val>
Params: int_pin                 GPIO used for IRQ (default 24)addr                    Address (default 0x48)xtal                    On-board crystal frequency (default 14745600)Name:   sc16is752-i2c
Info:   Overlay for the NXP SC16IS752 dual UART with I2C InterfaceEnables the chip on I2C1 at 0x48 (or the "addr" parameter value). Toselect another address, please refer to table 10 in reference manual.
Load:   dtoverlay=sc16is752-i2c,<param>=<val>
Params: int_pin                 GPIO used for IRQ (default 24)addr                    Address (default 0x48)xtal                    On-board crystal frequency (default 14745600)Name:   sc16is752-spi0
Info:   Overlay for the NXP SC16IS752 Dual UART with SPI InterfaceEnables the chip on SPI0.
Load:   dtoverlay=sc16is752-spi0,<param>=<val>
Params: int_pin                 GPIO used for IRQ (default 24)xtal                    On-board crystal frequency (default 14745600)Name:   sc16is752-spi1
Info:   Overlay for the NXP SC16IS752 Dual UART with SPI InterfaceEnables the chip on SPI1.N.B.: spi1 is only accessible on devices with a 40pin header, eg:A+, B+, Zero and PI2 B; as well as the Compute Module.Name:   uart0
Info:   Change the pin usage of uart0
Load:   dtoverlay=uart0,<param>=<val>
Params: txd0_pin                GPIO pin for TXD0 (14, 32 or 36 - default 14)rxd0_pin                GPIO pin for RXD0 (15, 33 or 37 - default 15)pin_func                Alternative pin function - 4(Alt0) for 14&15,7(Alt3) for 32&33, 6(Alt2) for 36&37Name:   uart1
Info:   Change the pin usage of uart1
Load:   dtoverlay=uart1,<param>=<val>
Params: txd1_pin                GPIO pin for TXD1 (14, 32 or 40 - default 14)rxd1_pin                GPIO pin for RXD1 (15, 33 or 41 - default 15)Name:   uart2
Info:   Enable uart 2 on GPIOs 0-3. BCM2711 only.
Load:   dtoverlay=uart2,<param>
Params: ctsrts                  Enable CTS/RTS on GPIOs 2-3 (default off)Name:   uart3
Info:   Enable uart 3 on GPIOs 4-7. BCM2711 only.
Load:   dtoverlay=uart3,<param>
Params: ctsrts                  Enable CTS/RTS on GPIOs 6-7 (default off)Name:   uart4
Info:   Enable uart 4 on GPIOs 8-11. BCM2711 only.
Load:   dtoverlay=uart4,<param>
Params: ctsrts                  Enable CTS/RTS on GPIOs 10-11 (default off)Name:   uart5
Info:   Enable uart 5 on GPIOs 12-15. BCM2711 only.
Load:   dtoverlay=uart5,<param>
Params: ctsrts                  Enable CTS/RTS on GPIOs 14-15 (default off)


2,以下为第二种方法:

sudo raspi-config

找到Interfacing选项,找到serial。
第一个问题是:would you like a login shell to be accessible  over serial? 选否。
第二个问题是would you like the serial port hardware to be enabled?选是。
我用的系统版本是2018-11-13-raspbian-stretch,你的问题顺序可能不一样,看清对应问题选择。

补充

/dev/serial0(对应的shell串口,有引脚引出) ->ttyS0(mini串口,用的是内核时钟不稳定,实际测试关闭shell之后并没有出现过异常情况)
/dev/serial1(对应的蓝牙,没有引脚引出) ->ttyAMA0(硬件串口稳定)

cd /boot/overlays/#提供了README

 

Name:   disable-bt
Info:   Disable onboard Bluetooth on Pi 3B, 3B+, 3A+, 4B and Zero W, restoringUART0/ttyAMA0 over GPIOs 14 & 15.N.B. To disable the systemd service that initialises the modem so itdoesn't use the UART, use 'sudo systemctl disable hciuart'.
Load:   dtoverlay=disable-bt
Params: <None>

README文件中说明了这个文件的功能是将树莓派3的蓝牙切换到mini串口(ttyS0),并且恢复硬件串口(ttyAMA0)到GPIO 14&15脚中。并且给出了载入的方法。

 

ls -l /dev

 此时GPIO映射的串口是默认的/dev/ttyS0这个mini串口。

使用下面这条指令编辑 /boot/config.txt 文件

sudo nano /boot/config.txt

在该文件中增加一行代码

dtoverlay=disable-bt

然后保存文件,重启树莓派使之生效。
再通过 ls -l /dev 命令查看修改后的映射关系

对比修改前的关系,可以看出serial0和serial1 与 ttyAMA0和ttyS0的映射关系对换完成了,也就是ttyAMA0映射到了引出的GPIO Tx Rx上。

禁用串口的控制台功能

前面的步骤已经交换了硬件串口与mini串口的映射关系,但现在想使用树莓派外接串口模块进行通信还不行,因为树莓派IO引出的串口默认是用来做控制台使用的,它的初衷是为了在没有网络接口时,通过串口对树莓派进行相关的配置。因此需要禁用这个默认功能,使得串口为我们自由使用。

树莓派命令窗口中分别通过如下两个命令停止和禁用串口的控制台功能
 

sudo systemctl stop serial-getty@ttyAMA0.service
sudo systemctl disable serial-getty@ttyAMA0.service

由于我们前面已经交换了串口的映射关系,因此这里注意是ttyAMA0。

然后通过下列指令编辑cmdline.txt文件
sudo nano /boot/cmdline.txt

 然后看到里面类似如下的内容

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

把console=serial0,115200删掉 console=serial0,115200 ,剩下的内容类似如下

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

 然后重新启动树莓派,使修改生效

编写一个简单的串口程序

新建一个test.py文件

# -*- coding: utf-8 -*
import serial
import time
# 打开串口
ser = serial.Serial("/dev/ttyAMA0", 9600)
def main():while True:# 获得接收缓冲区字符count = ser.inWaiting()if count != 0:# 读取内容并回显recv = ser.read(count)print(recv)ser.write(recv)# 清空接收缓冲区ser.flushInput()# 必要的软件延时time.sleep(0.1)if __name__ == '__main__':try:main()except KeyboardInterrupt:if ser != None:ser.close()

小插曲

#这里switch_function(reading)返回值是数字,但是ser.write()填入的值是数字则意思是发送几个字节
#所以我们把这里整成字符串,格式是utf-8.
count = str(switch_function(reading))if count != 0:recv = count.encode('utf-8')ser.write(recv)
#python中的多线程def Tmer_task(processed_frame):print("收到识别指令,正在处理...")image_base64 = image_to_base64(processed_frame)if image_base64:print("正在识别垃圾类型,请稍候...")reading = analyze_meter_image(image_base64)if reading:print("=" * 30)print(f"识别结果: {reading}")print("=" * 30)count = str(switch_function(reading))if count != 0:recv = count.encode('utf-8')ser.write(recv)print("已发送指令,请等待垃圾处理完成")else:print("识别失败,请重试")def periodic_task(cap, interval):while True:ret, frame = cap.read()if not ret:print("无法获取摄像头画面")break# 处理图像(现在返回彩色图像)processed_frame = img_p(frame)# 显示实时画面#cv2.imshow('Camera Feed', processed_frame)# 调用任务处理函数Tmer_task(processed_frame)# 等待间隔时间time.sleep(interval)ask_thread = threading.Thread(target=periodic_task, args=(cap, 10))task_thread.start()


http://www.ppmy.cn/devtools/137770.html

相关文章

Android Audio实战——音频多声道基础适配(七)

通过《Android Audio基础——音频输出声道设置》这篇文章,我们了解了 Android 11 中通道掩码校验的时候最好只校验到 7.1 声道(8声道),而在通道常量参数中有定义了 7.1.2 声道(10 声道)和 7.1.4声道(12 声道)。如果这里我们 Android 11 的项目想要使用 7.1.4 声道就需要…

Android Audio实战——音频多声道混音适配(八)

上一篇文章我们修改了在 Android 11 中适配 7.1.4 声道的相关常量定义及部分代码,这里我们来看一下另外两个部分重要逻辑的修改及优化。 在音频处理过程中,经常需要将不同采样率的音频统一到相同的采样率,以便进行进一步处理。而在 AudioMixer 中,很可能会使用 AudioResamp…

Java图书管理系统(简易保姆级)

前面学习了这么多知识&#xff0c;为了巩固之前的知识&#xff0c;我们就要写一个图书管理系统来帮助大家复习&#xff0c;让大家的知识融会贯通~~~ 话不多说&#xff0c;直接开始今天的内容~ 首先呢&#xff0c;我们要有一个大体的思路&#xff1a; 实现效果思路有两种情况&a…

Vue 3 Teleport 教程

Vue 3 Teleport 教程 1. Teleport 是什么&#xff1f; Teleport 是 Vue 3 中引入的一个强大组件&#xff0c;它允许你将组件的一部分渲染到文档中的其他位置&#xff0c;而不受原始组件嵌套层级的限制。这个特性特别适合处理模态框、弹窗、通知等需要脱离普通文档流的场景。 …

视频推拉流EasyDSS互联网直播点播平台技术特点及应用场景剖析

在数字科技日新月异的今天&#xff0c;视频直播和点播已经成为互联网内容传播的重要方式之一。而互联网直播点播平台EasyDSS作为功能强大的流媒体直播点播视频能力平台&#xff0c;提供了一站式的视频推拉流、转码、直播、点播、时移回放、存储等视频服务&#xff0c;广泛应用于…

设计模式之破环单例模式和阻止破坏

目录 1. 序列化和反序列化2. 反射 这里单例模式就不多说了 23种设计模式之单例模式 1. 序列化和反序列化 这里用饿汉式来做例子 LazySingleton import java.io.Serializable;public class LazySingleton implements Serializable {private static LazySingleton lazySinglet…

使用 pycharm 新建不使用 python 虚拟环境( venv、conda )的工程

有时候我们发现一个好玩的 demo&#xff0c;想赶快在电脑上 pip install 一下跑起来&#xff0c;发现因为 python 的 venv、conda 环境还挺费劲的&#xff0c;因为随着时间的发展&#xff0c;之前记得很清楚的 venv、conda 的用法&#xff0c;不经常使用&#xff0c;半天跑不起…

2024下半年——【寒假】自学黑客计划(网络安全)

CSDN大礼包&#xff1a;&#x1f449;基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前言 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&a…