串口通信
1. 本节介绍
📝本节您将学习如何通过将PICO2开发板的GPIO引脚复用为串口(UART)功能并输出和接收串口数据;
🏆学习目标
1️⃣如何将引脚配置为UART模式,与外部串口(UART)设备进行发送和接收数据。
2️⃣如何进行简单的串口回环测试。
2. 串口通信介绍
串口是指外设和处理器之间通过数据信号线、地线和控制线等,按位进行传输数据的一种通讯方式。尽管传输速度比并行传输低。但串口可以在使用一根线发送数据的同时用另一根线接收数据。 这种通信方式使用的数据线少,在远距离通信中可以节约通信成本。
串口通信最重要的参数是波特率、数据位、停止位和奇偶校验位,这些参数在两个通信端口之间必须一致。
串口通信参数介绍
串口通信参数包括波特率(Baud Rate)、数据位(Data Bits)、校验位(Parity Bits)、停止位(Stop Bits)等。这些参数描述了传输数据的基本规格。例如,波特率定义了数据传输的速率,数据位确定每个数据字节中包含的位数,校验位用于数据的差错检测,停止位表示数据传输结束的标志等。
- 波特率:衡量通信速度的参数,它表示每秒钟传送的 bit 的个数。
- 数据位:衡量通信中实际数据位的参数,表示一个信息包里包含的数据位的个数。
- 停止位:用于表示单个信息包的最后位,典型值为 1、1.5 和 2 位。由于数据是在传输线上传输的,每个设备都有自己的时钟,很有可能在通信过程中出现不同步,停止位不仅仅表示传输的结束,还能提供校正时钟同步的机会。停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率也越慢。
- 奇偶检验位:表示一种简单的检查错误的方式。
关于更为详细的介绍请搜索百度。
串口通信的底层实现
串口通信协议定义了在串口上进行数据交换的规则和格式。常见的串口通信协议包括ASCII协议、Modbus协议、RS-232协议等。协议规定了数据的帧结构、数据格式、校验方式等,确保发送和接收双方按照相同的规则进行数据交换,从而实现数据的正确传输和解析。
串口通信是一位一位地传输,每传输一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。每一个字符的前面都有一位起始位(低电平),后面由 7 位数据位组成,接着是一位校验位,最后是停止位。停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。
![]() |
---|
优势及作用
串口是计算机和外部设备之间最常见的通信接口之一,具有重要的作用和广泛的应用。在计算机领域,串口的重要性体现在以下几个方面:
- 数据传输:串口是一种常用的数据传输接口。通过串口,计算机可以与各种外部设备进行数据交换和通信。无论是传感器、执行器、显示器、打印机还是其他外部设备,串口通信都可以实现数据的传输和控制。
- 远程控制和监控:串口通信被广泛应用于远程控制和监控领域。通过串口,计算机可以远程控制设备的动作,并实时监测设备的状态和数据信息。这在工业控制、自动化系统、远程监控等场景中具有重要的作用。
- 调试和故障排查:串口通信是调试和故障排查的重要工具。通过串口,计算机可以与嵌入式系统、单片机等进行通信,实时监控和调试程序,输出调试信息,进行错误定位和排查,并对系统进行状态监测和故障诊断。
- 硬件连接:串口可以作为计算机与各种外部设备之间的连接桥梁。通过串口,可以连接和控制各类外部设备,如传感器、执行器、外围设备等。串口能够提供稳定的数据传输和双向通信功能。
- 通信协议:串口通信协议是计算机与外部设备之间数据传输的规范和约定。通过定义不同的协议,可以实现不同设备之间的数据交互和通信。常见的串口通信协议有UART、RS-232、RS-485等。
总之,串口对于计算机和外部设备之间的通信具有重要的作用。它是数据传输、远程控制和监控、调试和故障排查的关键工具,是计算机与外部设备连接和通信的桥梁。通过串口通信,可以实现与各种外部设备的数据交互,提高系统的功能和性能。
3. RP2350的串口说明
有两个 UART
,UART0
和 UART1
。
UART0
可以映射到GPIO 0/1
、2/3
、12/13
、14/15
、16/17
和18/19
。UART1
可以映射到GPIO 4/5
、6/7
、8/9
、10/11
、20/21
、26/27
。
不是所有的引脚都支持串口功能,只有特定的引脚才支持。这个需要大家去根据数据手册进行查找。也可以参考下方我们总结的外设引脚分布图。
![]() |
---|
4. 串口通信的硬件连接
串口通信是要有两个设备,并且两个设备都有串口功能才能够通信。现在我们的开发板上的串口功能有了,那跟谁跟哪一个设备通信呢?
需要一个 USB转TTL模块
,它可以将USB的数据转为TTL的串口数据。通过这个模块我们就可以跟电脑通信,方便我们查看数据。
![]() | ![]() |
---|---|
5. 实现串口通信的方式
使用machine.UART
machine.UART
类是 MicroPython
中用于控制串口外设的核心模块。通过该模块,我们可以轻松地管理微控制器上的串口外设进行通信。
要使用 machine.UART
,需要导入该模块:
from machine import UART
构造函数
uart0 = UART(id, baudrate, bits, parity, stop, tx, rx ...)
参数说明
id:
使用的是哪一个串口号。使用UART0填0,使用UART1填1。baudrate:
串口波特率。bits:(可不配置):
数据位的位数,默认8位数据位。parity:(可不配置):
校验位的位数,默认无校验位。stop:(可不配置):
停止位的位数,默认1位停止位。tx:
串口的数据发送引脚配置,使用时请确保配置引脚支持串口功能。rx:
串口的数据接收引脚配置,使用时请确保配置引脚支持串口功能。
可能支持的其他仅关键字参数包括:
txbuf
指定 TX 缓冲区的字符长度。rxbuf
指定 RX 缓冲区的字符长度。timeout
指定等待第一个字符的时间(以毫秒为单位)。timeout_char
指定在字符之间等待的时间(以毫秒为单位)。invert
指定要反转的行。
示例:
from machine import UART
# 配置GPIO4/5为串口1的发送/接收引脚,波特率为9600
uart1 = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
2
3
方法总结
重新初始化引脚配置
UART.init(baudrate=9600, bits=8, parity=None, stop=1, *, ...)
使用给定的参数初始化 UART
总线。除了没有 id
参数,其他跟UART构造函数基本一致.
数据发送
UART.write(buf)
将字节缓冲区数据写入 UART
总线进行发送。
buf:
要写入的数据
返回值:写入或 None 超时的字节数。
数据接收
UART.read([nbytes])
读取字符。如果 nbytes
指定,则最多读取 nbytes
个字节,否则读取尽可能多的数据。字节。如果超时,它可能会更快返回。超时可在构造函数中配置。
返回值:包含读入字节的字节对象。None
超时时返回。
UART.readinto(buf[, nbytes])
将字节读入buf
。 如果 nbytes
指定,则最多读取那么多字节。否则,最多读取 len(buf)
字节。如果超时,它可能会更快返回。超时可在构造函数中配置。
返回值:读取并存储到 buf
或 None
超时的字节数。
UART.readline()
读取一行,以换行符结尾。如果达到超时,它可能会更快返回。超时可在构造函数中配置。
返回值:读取或 None
超时的行。
查询有无数据
UART.any()
返回一个整数,计算可以在不阻塞的情况下读取的字符数。如果没有可用字符,则返回 0
,如果有字符,则返回正数。即使有多个字符可供读取,该方法也可能返回 1。
6. 串口通信实验
🏆学习目标
1️⃣如何将引脚配置为UART模式,与外部串口(UART)设备进行发送和接收数据。
2️⃣如何进行简单的串口回环测试。
代码验证
将引脚配置为UART模式,与外部串口(UART)设备进行发送和接收数据。
这里使用USB转TTL模块,让RP2350与电脑进行串口通信。
from machine import UART
import time
# 初始化UART0,波特率为115200
# 配置该串口0的TX发送引脚为0,串口0的RX接收引脚为1
uart = UART(0, baudrate=115200, tx=0, rx=1)
# 确保UART已经初始化
if uart:
print("UART0 initialized")
# 发送一个字符串
uart.write('Hello from RP2350 UART0!\n')
# 主循环
while True:
# 检查是否有数据可读
if uart.any():
# 读取数据
data = uart.read()
# 打印接收到的数据
print('Received:', data.decode('utf-8'))
else:
print("Failed to initialize UART0")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
效果:
进行简单的串口回环测试
这里使用GPIO4/5创建UART1,将两个引脚短接。这样我们发数据出去就会被自己接收到,接收到后我们输出到IDE的REPL命令栏。
from machine import UART, Pin
import time
# 创建UART1实例,使用GPIO 4作为TX,GPIO 5作为RX
uart = UART(1, baudrate=115200, tx=Pin(4), rx=Pin(5))
# 确保UART1已经初始化
if uart:
print("UART1 initialized on GPIO 4 (TX) and GPIO 5 (RX)")
# 主循环
while True:
# 发送一个字符串
uart.write('Hello from RP2350 UART1!\n')
# 简单的延时,确保数据发送完成
time.sleep(0.1)
# 检查是否有数据可读
if uart.any():
# 读取数据
data = uart.read()
# 打印接收到的数据到REPL
print('Received:', data.decode('utf-8'))
# 简单的延时,避免CPU占用过高
time.sleep(0.5)
else:
print("Failed to initialize UART1")
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