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

发布时间:2026/11/3 22:54:45

基于小智派-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/10/24 7:56:22

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

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

2026/10/31 8:38:14

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

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

2026/11/1 4:06:29

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

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

2026/11/3 22:53:12

一枚回形针的百年传奇:发明史、力学与生活智慧

把这枚小家伙放在掌心,你大概率不会多看它一眼。它叫 paperclip,中文里更常被叫回形针或者曲别针,几乎从不缺席任何一张办公桌,却又几乎从未被正眼看过。前几天收拾抽屉,我从一堆缠在一起的回形针里捞出一把&#xff0…

2026/11/3 22:53:12

Paperclip:面向LLM工作流的声明式YAML编排规范

1. “Paperclip”不是回形针:一个被严重误读的AI工程代号 最近在多个技术社区和开发者群聊里,频繁看到有人问:“Paperclip 是不是某个新出的 AI 框架?”“Paperclip 和 OpenClaw、Claude 什么关系?”“React 项目里怎…

2026/11/3 22:53:12

Vim高效编辑:usr_10.txt核心技巧与实战应用

1. Vim高效编辑的核心技巧:usr_10.txt深度解析作为Vim用户手册中承上启下的关键章节,usr_10.txt专门讲解"Making big changes"(作较大改动)的高级编辑技术。这部分内容位于基础操作(usr_04.txt小改动&#x…

2026/11/3 22:53:12

S7-1200 V4.0+固件是ET200SP以太网通信的前提

简介:本资源是一份面向工业自动化初学者与西门子PLC工程师的实操指南,聚焦ET200SP分布式I/O与S7-1200 PLC之间以太网通信的完整配置流程,解决现场常见的连接建立、IP分配、IO控制器关联及地址未分配等典型问题。文档以CPU1214C(V4…

2026/11/3 22:53:12

AI工程从零构建:可测试、可回滚、可观测的生产级系统

1. 这不是“搭积木”,而是重建AI工程的地基“AI Engineering from Scratch”——看到这个标题,很多人第一反应是:“又要学Python?又要配CUDA?又要调参?”其实完全想偏了。我带过二十多个从零起步的AI工程团…

2026/11/3 22:48:12

小红书多账号运营解决方案与防关联技巧

1. 小红书多账号运营的痛点与解决方案对于内容创作者和营销从业者来说,小红书多账号运营一直是个令人头疼的问题。每次切换账号都需要重新登录,输入验证码,甚至频繁操作还会触发平台的风控机制。更不用说那些同时管理十几个甚至几十个账号的专…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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

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

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