基于小智派-LZ3863星闪开发版:OpenHarmony UART 外设开发 — UART2 串口通信

发布时间:2026/9/11 18:16:35

基于小智派-LZ3863星闪开发版:OpenHarmony UART 外设开发 — UART2 串口通信 1、实验简介参考网址https://gitee.com/Lockzhiner-Electronics/lz3863/tree/master/apps/b6_uart21.1、实验目的本实验旨在帮助学习者掌握 OpenHarmony 轻量系统中UARTUniversal Asynchronous Receiver/Transmitter通用异步收发器外设的基本使用方法。通过本实验你将学会理解 UART 串口通信的工作原理及帧格式使用 IoT Hardware 接口配置 GPIO 引脚复用为 UART2 的 TXD/RXD掌握 UART 中断回调接收模式实现非阻塞数据接收实现串口回声Echo功能完成数据的接收与回发完成案例代码的编译、烧录与串口现象观察。1.2、实验内容本案例在 LZ3863-星闪开发板上通过UART2接口实现与外部设备如 PC 端 USB 转串口模块的双向通信。开发板接收外部发送的数据后自动将数据以[Echo]前缀回发并在串口输出接收与发送日志。项目说明UART 端口UART2UART_ID 2RXD 引脚GPIO7IOT_IO_FUNC_GPIO_7_UART2_RXDTXD 引脚GPIO8IOT_IO_FUNC_GPIO_8_UART2_TXD波特率115200数据格式8 位数据位、1 位停止位、无校验8N1接收模式非阻塞 中断回调发送模式阻塞发送接收缓冲区64 字节RECV_BUF_SIZE初始化入口uart2_callback_only_init程序在系统启动时通过APP_FEATURE_INIT自动完成 UART2 初始化注册接收中断回调后进入待命状态当外部设备发送数据时回调函数自动处理接收、日志打印与回声回发无需主线程轮询。1.3、实验环境项目说明硬件LZ3863-星闪开发板、USB 数据线、USB 转串口模块或杜邦线连接 PC 串口软件OpenHarmony v5.1.0 源码、hb 编译工具、串口调试助手调试工具串口助手波特率 1152008N1案例路径applications/sample/wifi-iot/app/b6_uart2/2、基础知识2.1、什么是 UARTUART通用异步收发器是一种常用的异步串行通信接口仅需TXD发送和RXD接收两根信号线外加 GND 地线即可实现设备间的点对点数据传输。UART 通信的核心特点概念说明异步通信无需共享时钟线收发双方通过约定的波特率同步全双工TXD 与 RXD 独立可同时发送和接收帧格式通常包含起始位、数据位、可选校验位、停止位点对点两设备间直接连接不支持多设备总线挂载本实验采用8N1格式8 位数据位、无校验位None、1 位停止位波特率 115200 bps。2.2、UART 硬件连接UART 通信采用交叉连接方式外部设备 TXD ──→ 开发板 RXDGPIO7 / UART2_RXD 外部设备 RXD ←── 开发板 TXDGPIO8 / UART2_TXD 外部设备 GND ──→ 开发板 GND注意UART 为 TTL 电平通常 3.3 V请勿直接与 RS-232 电平设备连接需使用电平转换模块。2.3、引脚复用MuxWS63 芯片的 GPIO7、GPIO8 可复用为 UART2 的 RXD 和 TXD。使用前必须通过IoSetFunc()将引脚功能设置为 UART 模式IoSetFunc(IOT_IO_NAME_GPIO_7,IOT_IO_FUNC_GPIO_7_UART2_RXD);// GPIO7 - UART2_RXDIoSetFunc(IOT_IO_NAME_GPIO_8,IOT_IO_FUNC_GPIO_8_UART2_TXD);// GPIO8 - UART2_TXD2.4、中断回调接收模式本案例采用中断回调模式接收数据相比轮询方式具有以下优势对比项轮询模式中断回调模式CPU 占用需持续查询接收缓冲区有数据时才触发处理实时性取决于轮询间隔数据到达即响应代码结构主循环中反复调用IoTUartRead()注册回调函数事件驱动工作流程外部设备发送数据 → UART 硬件接收 → 触发接收中断 → 调用 uart2_rx_callback() → 拷贝数据 → 打印日志 → 回声回发2.5、软件调用层次本案例的软件调用层次如下应用层uart2_example.c ├── IoSetFunc() ← 引脚复用为 UART2 ├── IoTUartInit() ← 初始化 UART 通信参数 ├── uapi_uart_register_rx_callback() ← 注册接收中断回调 ├── uapi_uart_write() ← 发送数据 └── uart2_rx_callback() ← 接收中断回调处理 └── uart2_log() ← 格式化日志输出 └── IoT Hardware / HAL 层2.6、核心 API 介绍2.6.1、头文件#includestdio.h#includestring.h#includestdarg.h#includestdbool.h#includeohos_init.h#includecmsis_os2.h#includeiot_gpio.h#includeiot_gpio_ex.h#includeiot_uart.h#includeiot_errno.h#includeuart.h2.6.2、UART 常用 APIAPI 名称功能说明IoSetFunc设置引脚复用功能UART TXD/RXDIoTUartInit初始化 UART 端口配置波特率、数据位等参数IoTUartRead主动读取 UART 接收缓冲区数据轮询模式IoTUartWrite向 UART 发送数据IoT Hardware 层uapi_uart_write向 UART 发送数据驱动层支持超时控制uapi_uart_register_rx_callback注册 UART 接收中断回调函数2.6.3、IoTUartInit — 初始化 UARTunsignedintIoTUartInit(unsignedintid,constIotUartAttribute*param);参数说明idUART 端口号本案例为2UART2param指向IotUartAttribute结构体配置通信参数IotUartAttribute结构体主要字段字段说明baudRate波特率如115200dataBits数据位如IOT_UART_DATA_BIT_8stopBits停止位如IOT_UART_STOP_BIT_1parity校验位如IOT_UART_PARITY_NONErxBlock接收阻塞模式IOT_UART_BLOCK_STATE_NONE_BLOCK表示非阻塞txBlock发送阻塞模式IOT_UART_BLOCK_STATE_BLOCK表示阻塞发送2.6.4、uapi_uart_register_rx_callback — 注册接收回调errcode_tuapi_uart_register_rx_callback(uart_bus_tbus,uart_rx_condition_tcondition,uint16_tthreshold,UartRxCallbackFunc callback);参数说明busUART 总线编号本案例为2condition触发条件本案例为UART_RX_CONDITION_FULL_OR_IDLE缓冲区满或空闲时触发threshold触发阈值字节数本案例为1收到 1 字节即触发callback接收回调函数指针2.6.5、uapi_uart_write — 发送数据intuapi_uart_write(uart_bus_tport,constuint8_t*data,uint32_tlen,uint32_ttimeout);参数说明portUART 端口号data待发送数据缓冲区指针len发送数据长度字节timeout超时时间本案例使用1表示阻塞等待发送完成2.6.6、APP_FEATURE_INIT — 应用入口注册APP_FEATURE_INIT(uart2_callback_only_init);该宏将uart2_callback_only_init注册为应用特性初始化函数系统启动完成后自动调用无需手动修改main()函数。3、程序设计3.1、程序架构本案例目录结构b6_uart2/ ├── uart2_example.c # 主程序源码 ├── BUILD.gn # GN 编译配置 ├── README_zh.md # 案例简要说明 └── 实验手册.md # 本实验手册本案例采用事件驱动 中断回调结构系统启动 │ ▼ uart2_callback_only_init() ← APP_FEATURE_INIT 注册系统启动时自动执行 │ ▼ uart2_init() ← UART2 初始化 ├── IoSetFunc() ← GPIO7/8 复用为 UART2 RXD/TXD ├── IoTUartInit() ← 配置 115200 8N1 ├── uapi_uart_register_rx_callback() ← 注册接收回调 └── 输出启动信息 hello uart2 │ ▼外部设备发送数据时触发 uart2_rx_callback() ← 接收中断回调 ├── 防重入保护 数据拷贝 ├── uart2_log() 打印接收日志 ├── 构建 [Echo] xxx 回发数据 └── uapi_uart_write() 发送回声3.2、源文件说明文件说明uart2_example.c主程序源码包含 UART2 初始化、接收回调与回声逻辑BUILD.gnGN 编译配置文件定义静态库uart2_example3.3、关键代码分析1宏定义 — UART 核心配置#defineUART_ID2// 目标 UART 端口号UART2#defineBAUDRATE115200// 通信波特率#defineRECV_BUF_SIZE64// 接收数据缓冲区大小#defineRX_TRIGGER_THRESHOLD1// 接收中断触发阈值1 字节触发#defineLOG_BUF_SIZE128// 日志格式化缓冲区大小2全局变量 — 状态与缓冲区staticunsignedcharg_recv_buf[RECV_BUF_SIZE]{0};// 接收数据缓冲区staticvolatilebool g_is_rx_processingfalse;// 接收处理状态标记防中断重入staticvolatilebool g_uart2_initedfalse;// UART2 初始化完成标记g_is_rx_processing用于防止回调函数重入若上一次接收尚未处理完毕新的中断将被忽略。3UART2 初始化 — uart2_inituart2_init完成引脚复用、UART 参数配置、接收回调注册并在成功后输出启动信息staticintuart2_init(void){// 配置 GPIO 引脚功能复用为 UART2 的 RXD 和 TXDIoSetFunc(IOT_IO_NAME_GPIO_7,IOT_IO_FUNC_GPIO_7_UART2_RXD);IoSetFunc(IOT_IO_NAME_GPIO_8,IOT_IO_FUNC_GPIO_8_UART2_TXD);// 配置 UART 通信参数8 位数据位1 位停止位无校验位IotUartAttribute uart_attr{.baudRateBAUDRATE,.dataBitsIOT_UART_DATA_BIT_8,.stopBitsIOT_UART_STOP_BIT_1,.parityIOT_UART_PARITY_NONE,.rxBlockIOT_UART_BLOCK_STATE_NONE_BLOCK,// 接收非阻塞中断模式.txBlockIOT_UART_BLOCK_STATE_BLOCK,// 发送阻塞.pad0};if(IoTUartInit(UART_ID,uart_attr)!IOT_SUCCESS){return-1;}// 注册接收中断回调函数errcode_tretuapi_uart_register_rx_callback(UART_ID,UART_RX_CONDITION_FULL_OR_IDLE,RX_TRIGGER_THRESHOLD,uart2_rx_callback);if(ret!ERRCODE_SUCC){return-1;}g_uart2_initedtrue;uart2_log(UART2 Init Success! Baudrate: %d\n,BAUDRATE);uapi_uart_write(UART_ID,(uint8_t*)hello uart2\n,12,1);return0;}4接收中断回调 — uart2_rx_callback当 UART2 接收到数据时驱动自动调用此回调函数完成数据拷贝、日志打印与回声回发staticvoiduart2_rx_callback(constvoid*buffer,uint16_tlength,bool error){unused(error);// 防重入保护 有效性校验if(g_is_rx_processing||bufferNULL||length0||lengthRECV_BUF_SIZE){return;}g_is_rx_processingtrue;// 拷贝接收数据到本地缓冲区memcpy(g_recv_buf,buffer,length);g_recv_buf[length]\0;// 打印接收日志uart2_log(Recv: Len%d, Data%s\n,length,g_recv_buf);// 构建回发数据charsend_back_buf[RECV_BUF_SIZE20]{0};snprintf(send_back_buf,sizeof(send_back_buf),[Echo] %s\n,g_recv_buf);// 发送回声数据intsend_lenuapi_uart_write(UART_ID,(uint8_t*)send_back_buf,strlen(send_back_buf),1);if(send_len0){uart2_log(Echo Send: Len%d, Data%s,send_len,send_back_buf);}else{uart2_log(Echo Send Failed! Len: %d\n,send_len);}g_is_rx_processingfalse;}5日志打印 — uart2_loguart2_log是 UART2 专用日志函数仅在初始化完成后生效通过vsnprintf格式化后发送到 UART2staticvoiduart2_log(constchar*format,...){if(!g_uart2_inited)return;va_list args;va_start(args,format);charlog_buf[LOG_BUF_SIZE]{0};vsnprintf(log_buf,LOG_BUF_SIZE-1,format,args);va_end(args);uapi_uart_write(UART_ID,(uint8_t*)log_buf,strlen(log_buf),1);}6应用启动入口 — uart2_callback_only_init系统启动后通过APP_FEATURE_INIT宏自动调用此函数完成 UART2 初始化staticvoiduart2_callback_only_init(void){if(uart2_init()!0){uapi_uart_write(UART_ID,(uint8_t*)UART2 Init Failed!\n,18,1);}}APP_FEATURE_INIT(uart2_callback_only_init);3.4、程序执行流程外部设备(PC)uart2_rx_callbackUART2 硬件uart2_callback_only_init系统启动外部设备(PC)uart2_rx_callbackUART2 硬件uart2_callback_only_init系统启动APP_FEATURE_INIT 触发IoSetFunc(GPIO7/8) IoTUartInit()uapi_uart_register_rx_callback()hello uart2 初始化成功日志发送数据 OpenHarmony触发接收中断回调拷贝数据 打印 Recv 日志uapi_uart_write([Echo] OpenHarmony)回发回声数据打印 Echo Send 日志4、编译步骤4.1、确认案例目录确认案例已位于 OpenHarmony 源码目录下applications/sample/wifi-iot/app/b6_uart2/ ├── uart2_example.c ├── BUILD.gn ├── README_zh.md └── 实验手册.md若从外部复制请将b6_uart2目录放到上述app/路径下。4.2、修改 BUILD.gn注册编译组件编辑applications/sample/wifi-iot/app/BUILD.gn在features列表中添加本案例lite_component(app) { features [ startup, b6_uart2:uart2_example, // 添加此行 ] }4.3、修改 SDK 配置文件步骤 1编辑device/soc/hisilicon/ws63v100/sdk/build/config/target_config/ws63/config.py找到ws63-liteos-app配置段在其ram_component列表中添加uart2_example步骤 2编辑device/soc/hisilicon/ws63v100/sdk/libs_url/ws63/cmake/ohos.cmake找到ws63-liteos-app对应的set(COMPONENT_LIST部分添加uart2_example4.4、执行编译在 OpenHarmony 源码根目录下执行rm-rfout hbset-root.# 通过上下方向键选择 ws63 对应的编译分支如 nearlink_dk_3863 / ws63-liteos-apphb build-f编译成功后固件输出路径通常在out/ws63/目录下。4.5、烧录固件使用开发板配套的烧录工具将编译生成的固件烧写到 LZ3863-星闪开发板。具体烧录步骤请参考开发板用户手册。5、运行结果5.1、硬件连接将 USB 转串口模块与开发板 UART2 引脚连接USB 转串口模块开发板引脚说明TXDGPIO7UART2_RXD模块发送 → 开发板接收RXDGPIO8UART2_TXD开发板发送 → 模块接收GNDGND共地5.2、串口配置打开 PC 端串口调试助手配置参数如下参数值波特率115200数据位8停止位1校验位无流控无5.3、预期现象烧录并复位开发板后串口助手可观察到1上电初始化输出hello uart2 UART2 Init Success! Baudrate: 1152002发送数据后的回声响应在串口助手发送区输入OpenHarmony并发送接收区将显示Recv: Len12, DataOpenHarmony [Echo] OpenHarmony Echo Send: Len20, Data[Echo] OpenHarmony其中Recv行为开发板接收日志显示接收字节数与内容[Echo] OpenHarmony为开发板回发的回声数据Echo Send行为回发日志显示发送字节数与内容。5.4、结果分析现象说明输出hello uart2UART2 初始化成功发送通道正常输出UART2 Init Success!uart2_log()日志函数工作正常收到[Echo] xxx接收中断回调触发成功回声逻辑正常无任何输出可能引脚连接错误或波特率不匹配输出乱码波特率或数据格式配置不一致输出UART2 Init Failed!GPIO 复用或 UART 初始化失败输出Register UART RX Callback Failed!接收回调注册失败5.5、常见问题排查问题可能原因解决方法完全无串口输出案例未加入编译或烧录了错误固件核对 4.2、4.3 节三处配置重新编译烧录有初始化信息但发送无响应TXD/RXD 接反或未共地确认交叉连接模块 TXD → 开发板 RXDGPIO7接收数据乱码波特率不一致确认双方均为 115200 8N1只能收不能发或反之单根信号线接触不良检查杜邦线连接测量引脚电压快速连续发送丢数据接收缓冲区仅 64 字节降低发送频率或增大RECV_BUF_SIZE编译报错找不到uart2_exampleBUILD.gn 或 config.py 未正确修改逐步核对 4.2、4.3 节的配置项6、实验扩展完成基本实验后可尝试以下扩展练习修改波特率将BAUDRATE改为9600或921600观察通信是否正常理解波特率匹配的重要性轮询接收对比去掉中断回调改用osThreadNew创建线程循环调用IoTUartRead()对比 CPU 占用与响应延迟协议解析在回调中解析固定格式的命令如LED ON\r\n结合b1_led_gpio案例控制 LED 亮灭数据透传将 UART2 接收的数据转发到 UART0调试串口实现双串口透传网关超时组帧利用UART_RX_CONDITION_FULL_OR_IDLE的空闲触发特性实现按帧接收不定长数据包增大缓冲区修改RECV_BUF_SIZE为 256 或 512测试长数据包的接收与回声能力结合传感器实验配合其他外设案例将传感器读数通过 UART2 定时上报给上位机。
延伸阅读

更多相关文章

2026/9/11 8:01:02

iPhone省电优化全攻略:延长续航的关键设置

1. iPhone省电优化的核心思路作为一名长期使用iPhone的深度用户,我发现在日常使用中电池续航是最影响体验的因素之一。很多人抱怨iPhone用久了会变卡顿、耗电快,其实这往往是因为忽略了一些系统自带的优化功能。经过多年实测,我发现通过合理设…

2026/9/2 10:36:24

真实攻防复盘:企业网站挂马入侵全过程拆解(从入侵到溯源清理)

📌 前言绝大多数新人只学靶场漏洞,从未见过真实入侵完整链路。真实黑客攻击不是单一漏洞点,而是漏洞利用→上传木马→权限维持→内网扩散→数据窃取的完整闭环。本文以一次真实企业官网挂马入侵事件做全流程复盘,带技术细节、阶段…

2026/9/5 16:20:39

HertzBeat无Agent监控:5分钟部署Linux服务器监控

1. 项目概述:HertzBeat与Linux监控的完美结合 作为一名运维工程师,我深知服务器监控的重要性。传统的监控方案如Zabbix、Prometheus虽然功能强大,但配置复杂、学习曲线陡峭。直到我遇到了HertzBeat这个开箱即用的开源监控工具,它彻…

2026/9/11 18:13:13

第33篇-架构评估(二):ATAM 方法与评估实战

【软考系统架构设计师全链路通关实战】第 33 篇:架构评估(二):ATAM 方法与评估实战 本系列定位:以软考系统架构设计师(高级)考试为主线,语言无关的架构方法论视角,覆盖官…

2026/9/11 18:13:13

深度迁移学习水质预测算法源码解析与实战指南

简介:基于深度迁移学习的水质预测研究算法源码,是一份面向计算机、数学、电子信息等专业课程设计、期末大作业及毕设项目的完整工程代码。项目以水质预测为应用场景,覆盖数据加载、时间特征生成、模型构建、迁移学习训练和结果评估等环节&…

2026/9/11 18:13:13

第34篇-CBAM 成本效益分析与架构脆弱性

【软考系统架构设计师全链路通关实战】第 34 篇:CBAM 成本效益分析与架构脆弱性 本系列定位:以软考系统架构设计师(高级)考试为主线,语言无关的架构方法论视角,覆盖官方教程(第二版)…

2026/9/11 18:08:12

【Python 基础】FastAPI ORM 操作MySql 实战使用详解

目录 一、前言 二、FastAPI ORM介绍 2.1 什么是 ORM 2.2 ORM 的优势 2.3 ORM 常用框架 2.4 ORM的使用流程 三、FastAPI ORM 使用 3.1 前置准备 3.1.1 安装依赖包 3.2 ORM 基本使用 3.2.1 创建数据库 3.2.2 创建会话工厂 3.2.3 新增数据 3.2.4 修改数据 3.2.5 查询…

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码