UART

UART 实现标准 UART/USART 双工串行通信协议。在物理层面上,它由 2 条线路组成:RX 和 TX。通信单位是一个字符(不要与字符串字符混淆),可以是 8 位或 9 位宽。

UiFlow2 应用示例

回声

在 UiFlow2 中打开 cores3_echo_exmaple.m5f2 项目。

此示例演示了如何利用 UART 接口,通过将配置的 UART 上接收到的任何数据回传给发送方。

UiFlow2 代码块:

cores3_echo_exmaple.png

示例输出:

None

MicroPython 应用示例

回声

此示例演示了如何利用 UART 接口,通过将配置的 UART 上接收到的任何数据回传给发送方。

MicroPython 代码块:

 1# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
 2#
 3# SPDX-License-Identifier: MIT
 4
 5import os, sys, io
 6import M5
 7from M5 import *
 8from hardware import UART
 9import time
10
11
12label0 = None
13uart1 = None
14
15
16i = None
17
18
19def setup():
20    global label0, uart1, i
21
22    M5.begin()
23    Widgets.fillScreen(0x222222)
24    label0 = Widgets.Label("label0", 102, 85, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
25
26    uart1 = UART(1, baudrate=115200, bits=8, parity=None, stop=1, tx=9, rx=10)
27    i = 0
28
29
30def loop():
31    global label0, uart1, i
32    M5.update()
33    uart1.write(i)
34    if uart1.any():
35        label0.setText(str(uart1.read()))
36    i = (i if isinstance(i, (int, float)) else 0) + 1
37    time.sleep(1)
38
39
40if __name__ == "__main__":
41    try:
42        setup()
43        while True:
44            loop()
45    except (Exception, KeyboardInterrupt) as e:
46        try:
47            from utility import print_error_msg
48
49            print_error_msg(e)
50        except ImportError:
51            print("please update to latest firmware")

示例输出:

None

API参考

class UART

class UART(id, baudrate=9600, bits=8, parity=None, stop=1, *, ...)

构造给定 id 的 UART 对象。

更多参数请参考 init 。

UiFlow2 代码块:

init.png

MicroPython 代码块:

from hadrware import UART

uart1 = UART(1, baudrate=115200, bits=8, parity=None, stop=1, tx=9, rx=10)
init(baudrate=9600, bits=8, parity=None, stop=1, *, ...)

使用给定的参数初始化 UART 总线。

参数:
  • baudrate (int) – 时钟频率。

  • bits (int) – 每个字符的位数,7、8 或 9。

  • parity (None or int) – 奇偶校验,“无”,0(偶数)或 1(奇数)。

  • stop (int) – 停止位数,1 或 2。

关键字参数:
  • tx – 要使用的 TX 引脚。

  • rx – 要使用的 RX 引脚。

  • rts – 用于硬件接收流控制的 RTS(输出)引脚。

  • cts – 用于硬件传输流控制的 CTS(输入)引脚。

  • txbuf (int) – TX 缓冲区的长度(以字符为单位)。

  • rxbuf (int) – RX 缓冲区的长度(以字符为单位)。

  • timeout (int) – 等待第一个字符的时间(以毫秒为单位)。

  • timeout_char (int) – 字符之间等待的时间(以毫秒为单位)。

  • invert (int) – 选择要反相的线。 - 0 将不会反相线(两条线的空闲状态均为逻辑高)。 - UART.INV_TX 将反相 TX 线(TX 线的空闲状态变为逻辑低)。 - UART.INV_RX 将反相 RX 线(RX 线的空闲状态变为逻辑低)。 - UART.INV_TX | UART.INV_RX 将反相两条线(空闲状态为逻辑低)。

  • flow (int) – 选择使用哪些硬件流控信号。该值为位掩码。

  • mode (int) – UART 的模式。该值为位掩码。

备注

可以对同一对象多次调用 init() ,以便动态重新配置 UART。这样可以使用单个 UART 外设来为连接到不同 GPIO 引脚的不同设备提供服务。在这种情况下,一次只能为一个设备提供服务。另外,不要调用 deinit() ,因为它会阻止再次调用 init()

UiFlow2 代码块:

setup.png

MicroPython 代码块:

uart1.init(baudrate=115200, bits=8, parity=None, stop=1, tx=9, rx=10)
deinit()

关闭 UART 总线。

备注

deinit() 之后,您将无法在对象上调用 init() 。在这种情况下,需要创建一个新实例。

UiFlow2 代码块:

deinit.png

MicroPython 代码块:

uart1.deinit()
any()

返回一个整数,表示可以无阻塞读取的字符数。如果没有可用字符,则返回 0;如果有字符,则返回一个正数。即使有多个字符可供读取,该方法也可能返回 1。

返回:

可读取的字符数。

返回类型:

int

对于更复杂的可用字符查询,请使用 select.poll:

poll = select.poll()
poll.register(uart, select.POLLIN)
poll.poll(timeout)

UiFlow2 代码块:

any.png

MicroPython 代码块:

print(uart1.any())
read([nbytes])

读取字符。如果指定了 nbytes,则最多读取那么多字节,否则读取尽可能多的数据。如果达到超时,它可能会更早返回。超时可以在构造函数中配置。

返回:

包含读入字节的字节对象。超时时返回 None

返回类型:

bytes or None

UiFlow2 代码块:

read_all.png

read_bytes.png

read_raw_data.png

MicroPython 代码块:

print(uart1.read())
readinto(buf[, nbytes])

将字节读入 buf 。如果指定了 nbytes ,则最多读取那么多字节。否则,最多读取 len(buf) 个字节。如果达到超时,它可能会更早返回。超时可以在构造函数中配置。

返回:

超时时读取并存储到 bufNone 中的字节数。

返回类型:

int or None

UiFlow2 代码块:

readinto.png

MicroPython 代码块:

buf = bytearray(10)
uart1.readinto(buf)
readline()

读取一行,以换行符结尾。如果达到超时,它可能会更快返回。超时可在构造函数中配置。

返回:

超时时读取的行或 None

返回类型:

str or None

UiFlow2 代码块:

readline.png

MicroPython 代码块:

print(uart1.readline())
write(buf)

将字节缓冲区写入总线。

参数:

buf (bytes or bytearray or str) – 要写入的字节缓冲区。

返回:

超时时写入的字节数或 None

返回类型:

int or None

UiFlow2 代码块:

write.png

write1.png

write_line.png

write_list.png

write_raw_data.png

write_raw_data_list.png

MicroPython 代码块:

uart1.write('1234!')
sendbreak()

在总线上发送中断条件。这会将总线驱动为低电平,持续时间比正常传输字符所需的时间更长。

UiFlow2 代码块:

sendbreak.png

MicroPython 代码块:

uart1.sendbreak()
flush()

等待所有数据发送完毕。如果发生超时,则会引发异常。超时持续时间取决于 tx 缓冲区大小和波特率。除非启用了流量控制,否则不应发生超时。

备注

对于 rp2、esp8266 和 nrf 端口,调用将在发送最后一个字节时返回。如果需要,必须在调用脚本中添加一个字符的等待时间。

UiFlow2 代码块:

flush.png

MicroPython 代码块:

uart1.flush()
txdone()

告知是否已发送所有数据或未发生任何数据传输。在这种情况下,它返回 True 。如果正在进行数据传输,则返回 False

备注

对于 rp2、esp8266 和 nrf 端口,即使传输的最后一个字节仍在发送,调用也可能返回 True 。如果需要,必须在调用脚本中添加一个字符的等待时间。

UiFlow2 代码块:

txdone.png

MicroPython 代码块:

print(uart1.txdone())
irq(handler=None, trigger=0, hard=False)

配置一个中断处理程序,在发生 UART 事件时调用。

参数:
  • handler (func) – 中断事件触发时调用的可选函数。处理程序必须只接受一个参数,即 UART 实例。

  • trigger (int) – 配置可生成中断的事件。可能的值为以下一个或多个事件的掩码:

  • hard (bool) – 如果为真,则使用硬件中断。这减少了引脚变化和调用处理程序之间的延迟。硬中断处理程序可能不会分配内存;请参阅 Writing interrupt handlers

返回:

返回一个 irq 对象。

由于硬件的限制,并非所有触发事件都可在所有端口上使用。

触发器的可用性

端口 / 触发器

IRQ_RXIDLE

IRQ_RX

IRQ_TXIDLE

IRQ_BREAK

CC3200

yes

ESP32

yes

yes

yes

MIMXRT

yes

yes

NRF

yes

yes

RENESAS-RA

yes

yes

RP2

yes

yes

yes

SAMD

yes

yes

yes

STM32

yes

yes

备注

  • ESP32 端口不支持选项 hard=True。

  • 仅当消息长度超过5个字符时,rp2端口的UART.IRQ_TXIDLE才会触发,并且当仍有5个字符需要发送时才会触发。

  • rp2端口的UART.IRQ_BREAK需要接收有效字符才能再次触发。

  • 发送最后一个字符时,触发SAND端口UART.IRQ IDLE。

  • 在 STM32F4xx MCU 上,使用触发器 UART.IRQ_RXIDLE,当线路空闲时,处理程序将在第一个字符之后调用一次,然后在消息结束后调用一次。

有效性:cc3200、esp32、mimxrt、nrf、renesas-ra、rp2、samd、stm32。

RTS
CTS

流量控制选项。

MODE_UART
MODE_RS485_HALF_DUPLEX
MODE_IRDA
MODE_RS485_COLLISION_DETECT
MODE_RS485_APP_CTRL

UART 模式选项。

IRQ_RXIDLE
IRQ_RX
IRQ_TXIDLE
IRQ_BREAK

IRQ 触发源。