跳转至

Uart demo

作者:陈媛媛 | 最后修改:2026-06-04

一、串口(UART)概述

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种常用的串行通信协议,广泛应用于单片机或各种嵌入式设备之间的通信。以下是 UART 的详细介绍:

1.1 UART 的基本概念

UART 是一种串行通信接口,它允许设备通过串行通信方式发送和接收数据。UART 通信是异步的,这意味着通信双方不需要共享一个时钟信号来同步数据传输。UART 通常用于嵌入式系统中,如微控制器与其他设备之间的数据交换。

1.2 UART 的物理连接

UART 通信通常只需要两条线:一条用于数据的发送(TX),一条用于数据的接收(RX)。此外,还需要一条地线(GND)来提供一个共同的参考电平,确保信号的准确性。在实际连接时,一个设备的 TX 线需要连接到另一个设备的 RX 线,反之亦然,这样才能实现双向通信。

1.3 UART 的数据格式

UART 的数据格式通常包含以下几个部分:

1.3.1 起始位(Start Bit)

  • 起始位是一个逻辑低电平(0),它标志着一个数据字符的开始。在进行数据传输过程中,数据线通常保持为高电平(空闲状态),当有数据要发送时,发送方会将数据线从高电平拉低,维持一个比特时间,这个低电平信号称为起始位。接收方检测到这个低电平后,便开始准备接收后续的数据位。

1.3.2 数据位(Data Bits)

  • 数据位紧跟在起始位之后,包含有实际要传输的数据。数据位的位数可以是 5 - 9 位,具体位数根据实际应用需求和协议约定来确定。
  • 例如,如果使用 8 位数据位,那么它可以表示 256(2⁸)种不同的数据值。对于常见的 ASCII 码字符传输,8 位数据位可以完整地表示一个字符,包括其字节值。

1.3.3 奇偶校验位(Parity Bit,可选)

  • 奇偶校验位用于错误检测。它可以是奇校验或偶校验。如果选择奇校验,发送方会根据数据位中 1 的个数来设置奇偶校验位的值,使得整个数据位(包括奇偶校验位)中 1 的个数为奇数。同样,偶校验则是让 1 的个数为偶数。接收方收到数据后,会根据约定的奇偶校验方式来检查数据的完整性。如果奇偶校验位与数据位的组合不符合约定的奇偶性规则,就认为数据传输过程中可能出现了错误。
  • 例如,假设数据位是 8 位,数据位中有 3 个 1,此时使用偶校验,那么奇偶校验位就设置为 1,使得整个数据(8 位数据位 + 1 位奇偶校验位)有 4 个 1,满足偶校验的要求。

1.3.4 停止位(Stop Bits)

  • 停止位位于数据帧的末尾,是一个或多个逻辑高电平(1)。它用于标志着一个数据字符的结束,并为接收方提供数据恢复时间。停止位的长度可以是 1 位、1.5 位或 2 位,具体取决于选用的 UART 配置。较长的停止位可以为接收方提供更充裕的时间来处理接收到的数据,但对于数据传输速率较高的情况,较短的停止位可以提高数据传输效率。

1.4 UART 的波特率

波特率(Baud Rate)是 UART 通信中最重要的参数之一,它定义了数据传输的速率,即每秒钟传输的位数。常见的波特率值有 300、600、1200、2400、4800、9600、19200、38400、57600、115200 等。波特率必须在通信双方之间进行匹配,否则数据将无法正确传输。

1.5 UART 的信号管脚

UART 的信号管脚主要包括以下几个:

1.5.1 基本信号管脚

  • TX(Transmit):发送数据管脚,用于将数据从发送端传输到接收端。
  • RX(Receive):接收数据管脚,用于接收来自发送端的数据。
  • GND(Ground):地线,用于提供信号的参考电平,确保发送和接收设备之间的电平一致。
  • VCC(Power Supply):电源管脚,为 UART 设备提供直流电源。

二、演示功能概述

本文将演示如何在 Air1601开发板上实现 UART(通用异步收发传输器)的通信。演示功能主要包括以下几个方面:

  1. 初始化 UART:将介绍如何配置 UART 的波特率、数据位、停止位和校验位等参数,并初始化 UART。
  2. 接收数据:将展示如何通过注册接收事件的回调函数接收来自 UART 的数据,并处理接收到的数据。
  3. 发送数据:将介绍如何使用 UART 的 API 接口发送数据,包括发送普通字符串、十六进制数据和 JSON 格式的数据。
  4. 单串口通信:将展示如何在 Air1601开发板上实现单串口通信,包括配置和发送接收数据的步骤。
  5. 单串口大数据通信:将展示如何在 Air1601开发板上实现大数据量的通信,包括配置和发送接收数据的步骤。
  6. 多串口通信:将展示如何在 Air1601开发板上实现多串口通信,包括配置和发送接收数据的步骤。

通过这些演示,大家可以了解如何在 Air1601开发板上实现 UART 通信,包括初始化、接收和发送数据、以及实现单串口、多串口通信等。

三、演示硬件环境

参考:硬件环境清单,准备以及组装好硬件环境。

购买链接:Air1601开发板 多功能5寸RGB屏 支持AirUI 摄像头 代开发固件-淘宝网

四、准备软件环境

1.Luatools 工具

2.内核固件文件(底层 core 固件文件):LuatOS-SoC_V1004_Air1601.soc

3.luatos 需要的脚本和资源文件

  • 脚本和资源文件点击此处查看与下载

  • lib 脚本文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件;

准备好软件环境之后,接下来查看如何烧录项目文件到 Air1601 开发板中,将本篇文章中演示使用的项目文件烧录到Air1601开发板 中。

五、软硬件资料

5.1 uart 库介绍

5.1.1 主要功能介绍

uart 库即串口操作库,该库为内部库,因此在程序中使用时无需 require 调用。该库主要用于支持 UART(通用异步收发传输)功能,适用于一些嵌入式设备或平台。它使用 C 语言,并结合 Lua 脚本提供了一些 API 供用户方便地控制和操作串口。该库包含如下主要功能:

  • 初始化、配置和管理多个串口设备,包括支持软件 UART。

  • 发送和接收数据,支持串口的基本通信功能。

  • 提供事件回调机制,用户可以注册接收和发送的数据处理函数。

  • 允许用户检查串口的存在以及读取剩余数据缓存的大小。

5.1.2 API 接口介绍

本教程所用 API 接口参考:uart - 串口操作库

5.2 串口接线介绍

Air 1601 用户可用4个串口,分别为 UART1、UART2、UART3、UART5。

本文使用 UART1、UART2 进行演示。

特别说明,UART4 作为下载和调试专用串口,不能连接任何外设。

5.2.1 串口管脚位置说明

在进行复用之前请先参考:Air1601_1602管脚复用表

5.2.2 串口接线说明

接下来进行接线操作,Air1601开发板与 MCU/串口板 之间是 TX 接 RX,RX 接 TX,GND 接 GND 。

UART1 接线说明:

Air1601开发板
MCU或者串口板
UART1_TXD
UART_RXD
UART1_RXD
UART_TXD
GND
GND

UART2 接线说明:

Air1601开发板
MCU或者串口板
UART2_TXD
UART_RXD
UART2_RXD
UART_TXD
GND
GND

六、代码示例介绍

6.1 初始化

6.1.1 单串口

大家任选其中一个就行,本文使用 UART1 串口进行演示。

  • 使用 UART1 串口:
local uartid = 1 -- 使用uart1,可根据实际设备选取不同的uartid

--初始化 参数都可以根据实施情况修改
uart.setup(
    uartid,--串口id
    115200,--波特率
    8,--数据位
    1--停止位
)

6.1.2 多串口

本文以 UART1、UART2 串口进行演示.

-- 根据实际设备选取不同的uartid
local uartid1 = 1 -- 第一个串口id
local uartid2 = 2 -- 第二个串口id

-- 初始化第一个串口
uart.setup(
    uartid1,--串口id
    115200,--波特率
    8,--数据位
    1--停止位
)

-- 初始化第二个串口
uart.setup(
    uartid2,--串口id
    115200,--波特率
    8,--数据位
    1--停止位
)

6.2 注册接收数据的回调函数

uart.on 函数用于注册一个接收事件的回调函数,当指定的串口 uartid 接收到数据时,该回调函数会被自动触发并执行。回调函数通过 uart.on(uartid1, "receive", function(id, len) ... end) 定义,并处理接收到的数据。数据的读取是通过 uart.read() 函数进行的,uart.read() 函数是非阻塞的,它是直接从现有缓存区中直接读取数据。

-- 收取数据会触发回调, 这里的 "receive" 是固定值不要修改。
uart.on(uartid, "receive", function(id, len)
    local s = ""
    repeat
        s = uart.read(id, 128)
        if #s > 0 then -- #s 是取字符串的长度
            -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
            log.info("uart", "receive", id, #s, s)
            log.info("uart", "receive(hex)", id, #s, s:toHex())   -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到,可以用以hex格式打印
        end
    until s == ""
end)

使用 zbuff 接收数据:

local rxbuff = zbuff.create(10240) -- 接收数据的zbuff
local function uart_cb(id, len)  -- 串口接收数据回调函数
        while true do
            log.info("uart", "缓冲区", uart.rxSize(id))
            local len = uart.rx(id, rxbuff)
            if len <= 0 then
                break
            end
            log.info("uart", "receive", id, rxbuff:used(), rxbuff:toStr())
            rxbuff:seek(0)
        end
    end

6.3 注册数据发送完成的回调函数

uart.on 函数用于注册一个接收事件的回调函数,当指定的串口 数据发送完成时,该回调函数会被自动触发并执行。回调函数通过 uart.on(uartid1, "sent", function(id) ... end) 定义

local function uart_send_cb(id)
    log.info("uart", id , "数据发送完成回调")
end

6.4 发送数据

本文中字符串编码格式为 UTF-8 编码格式,SSCOM 串口调试工具无法正确显示字符串中的中文,需要注意。

  • 发送普通字符串
uart.write(uartid, "\r\nRDY\r\n模块型号:" .. hmeta.model())
  • 发送十六进制的数据串
uart.write(uartid, string.char(0x55,0xAA,0x4B,0x03,0x86))
  • 通过 zbuff 的方式发送数据
local buff = zbuff.create(1024)
buff:copy(0, "aa:bb:cc:dd, zbuff!")
uart.tx(uartid, buff)
  • 发送 json 格式的数据
local data =
{
    host = "abcdefg.com",
    port = "1883",
    clientID = "c88885",
    username = "user",
    password = "123456",
    ca_self = {ssl=false},
}

local jsondata = json.encode(data)
uart.write(uartid, jsondata)

七、功能验证

7.1 单串口

7.1.1 接线展示

下方为 UART1 的接线图

7.1.2 运行结果展示

7.2 多串口

7.2.1 接线展示

7.2.2 运行结果展示

7.3 单串口,大数据量收发

7.3.1 接线展示

下方为 UART1 的接线图

7.3.2 运行结果展示

七、总结

本文演示如何在 Air1601开发板上实现 UART(通用异步收发传输器)的通信。

八、常见问题

  1. 串口电平电压过低或过高可能会导致什么问题?

如果电压过低,可能会导致接收器无法正确识别信号,如果过高,可能会导致信号损坏或损坏接收器。 概述:可能会导致串口无法正常通讯,或通讯数据会突然出现乱码,数据错乱等问题。

  1. 有没有推荐的串口设计电路可以作为参考?

待补充