基于小智派-LZ3863星闪开发板:OpenHarmony WiFi 网络开发 — 热点创建与连接
1、实验简介
参考网址:https://gitee.com/Lockzhiner-Electronics/lz3863/tree/master/apps/c1_wifi_connect
1.1、实验目的
本实验旨在帮助学习者掌握 OpenHarmony 轻量系统中 WiFi 无线网络 的基本使用方法。通过本实验,你将学会:
- 理解 WiFi AP(Access Point,接入点) 与 STA(Station,站点) 两种工作模式;
- 在开发板上创建 SoftAP 热点,配置 SSID、密码、加密方式与信道;
- 在开发板上以 STA 模式扫描并连接指定热点,通过 DHCP 获取 IP 地址;
- 掌握 WiFi 事件回调、扫描、关联与 DHCP 的完整连接流程;
- 完成案例代码的编译、烧录与双板联调现象观察。
1.2、实验内容
本案例包含两个独立功能模块,分别编译烧录到两块开发板上联调:
| 模块 | 源文件 | 功能说明 |
|---|---|---|
| WiFi 热点模块(AP) | wifi_connect_example_AP.c |
创建名为 HiSpark_AP 的 WiFi 热点,启动 DHCP 服务器 |
| WiFi 连接模块(STA) | wifi_connect_example_STA.c |
扫描并连接 HiSpark_AP,保持连接 60 秒后自动断开 |
两个模块共用 wifi_connecter.c 中的底层封装接口,各自通过独立 RTOS 线程运行,互不耦合。
热点(AP)默认配置:
| 项目 | 说明 |
|---|---|
| SSID | HiSpark_AP |
| 密码 | 123456789 |
| 加密类型 | WIFI_SEC_TYPE_PSK(值为 2,WPA/WPA2-PSK) |
| 工作信道 | 7 |
| AP IP 地址 | 192.168.43.1 |
| 网关地址 | 192.168.43.2 |
| 网络接口 | ap0 |
连接(STA)默认配置:
| 项目 | 说明 |
|---|---|
| 目标 SSID | HiSpark_AP |
| 目标密码 | 123456789 |
| 连接保持时间 | 60 秒(每秒打印剩余倒计时) |
| IP 获取方式 | DHCP 动态获取 |
| 网络接口 | wlan0 |
1.3、实验环境
| 项目 | 说明 |
|---|---|
| 硬件 | 两块 LZ3863-星闪开发板、USB 数据线 |
| 软件 | OpenHarmony v5.1.0 源码、hb 编译工具 |
| 调试工具 | 串口助手(波特率 115200,用于查看日志) |
| 案例路径 | applications/sample/wifi-iot/app/c1_wifi_connect/ |
注意:本实验需要 两块开发板 分别烧录 AP 固件和 STA 固件,才能完成完整的 WiFi 连接联调。
2、基础知识
2.1、WiFi 工作模式
WiFi 设备通常支持以下两种基本工作模式:
| 模式 | 英文全称 | 角色 | 典型场景 |
|---|---|---|---|
| AP 模式 | Access Point | 接入点(热点) | 开发板创建热点,供手机或其他设备连接 |
| STA 模式 | Station | 无线站点(客户端) | 开发板连接路由器或另一块开发板的热点 |
本实验中:
- 开发板 A 运行 AP 模块,相当于一个微型路由器;
- 开发板 B 运行 STA 模块,相当于连接路由器的终端设备。
2.2、SoftAP 与 DHCP 服务
SoftAP(软件接入点) 指通过软件在 WiFi 芯片上模拟 AP 功能,无需额外硬件路由器。本案例 AP 模块调用 wifi_softap_enable() 启动热点,并通过 lwIP 协议栈在 ap0 接口上配置 DHCP 服务器(netifapi_dhcps_start),为连接的 STA 设备自动分配 IP 地址。
AP 侧网络参数:
IP 地址: 192.168.43.1
子网掩码:255.255.255.0
网关: 192.168.43.2
2.3、STA 连接流程
STA 模块的连接过程可分为以下阶段:
启用 STA 模式 → 扫描周围热点 → 匹配目标 SSID → 发起关联连接
→ 等待关联成功 → 启动 DHCP 客户端 → 获取 IP 地址 → 连接完成
各阶段通过 g_wifi_state 状态变量和 WiFi 事件回调函数协同推进。
2.4、WiFi 事件回调机制
STA 连接过程中,驱动通过事件回调通知应用层状态变化。本案例注册了两个回调:
| 回调函数 | 触发时机 | 处理逻辑 |
|---|---|---|
wifi_scan_state_changed |
扫描完成 | 打印日志,状态置为 SCAN_DONE |
wifi_connection_changed |
关联状态变化 | 连接成功置为 CONNECT_DONE,失败重新初始化 |
wifi_event_stru wifi_event_cb = {
.wifi_event_connection_changed = wifi_connection_changed,
.wifi_event_scan_state_changed = wifi_scan_state_changed,
};
2.5、软件调用层次
本案例的软件调用层次如下:
应用层(wifi_connect_example_AP.c / wifi_connect_example_STA.c)
├── StartHotspot() ← AP 模块:启动热点
├── ConnectToHotspot() ← STA 模块:连接热点
└── DisconnectWithHotspot() ← STA 模块:断开连接
│
封装层(wifi_connecter.c)
├── wifi_softap_enable() ← 启动 SoftAP
├── wifi_sta_enable/scan/connect() ← STA 扫描与连接
├── wifi_register_event_cb() ← 注册事件回调
└── netifapi_dhcp_start/stop() ← DHCP 客户端/服务器
│
协议栈 / 驱动层
├── lwIP 网络协议栈
└── WiFi 驱动(HMAC/DMAC)
2.6、核心 API 介绍
2.6.1、头文件
#include <stdio.h>
#include <string.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_device.h"
#include "wifi_connecter.h"
2.6.2、应用层封装 API
| API 名称 | 功能说明 |
|---|---|
StartHotspot(ssid, key, secType, channel) |
启动 WiFi 热点,返回 ERRCODE_SUCC 表示成功 |
ConnectToHotspot(ssid, password) |
扫描并连接指定热点,完成 DHCP 获取 IP |
DisconnectWithHotspot() |
停止 DHCP 并断开当前 WiFi 连接 |
2.6.3、WiFi 驱动 API
| API 名称 | 功能说明 |
|---|---|
wifi_softap_enable(&hapd_conf) |
启用 SoftAP,传入热点配置结构体 |
wifi_softap_disable() |
关闭 SoftAP |
wifi_sta_enable() |
启用 STA 模式 |
wifi_sta_scan() |
发起周围热点扫描 |
wifi_sta_get_scan_info() |
获取扫描结果列表 |
wifi_sta_connect(&config) |
连接指定热点 |
wifi_sta_disconnect() |
断开当前连接 |
wifi_sta_get_ap_info() |
获取当前连接状态信息 |
wifi_register_event_cb(&event_cb) |
注册 WiFi 事件回调 |
2.6.4、网络协议栈 API
| API 名称 | 功能说明 |
|---|---|
netif_find(ifname) |
按接口名查找网络接口(如 ap0、wlan0) |
netifapi_netif_set_addr() |
设置接口 IP、掩码、网关 |
netifapi_dhcps_start() |
启动 DHCP 服务器(AP 侧) |
netifapi_dhcp_start() |
启动 DHCP 客户端(STA 侧) |
netifapi_dhcp_is_bound() |
查询 DHCP 是否已绑定 |
netifapi_dhcp_stop() |
停止 DHCP 客户端 |
2.6.5、线程与系统入口 API
| API 名称 | 功能说明 |
|---|---|
osThreadNew(func, arg, &attr) |
创建 RTOS 线程 |
osDelay(ticks) |
线程延时,100 ticks ≈ 1 秒(tick = 10 ms) |
SYS_RUN(func) |
注册系统启动入口函数,上电后自动执行 |
3、程序设计
3.1、程序架构
本案例目录结构:
c1_wifi_connect/
├── wifi_connect_example_AP.c # AP 热点示例(烧录到开发板 A)
├── wifi_connect_example_STA.c # STA 连接示例(烧录到开发板 B)
├── wifi_connecter.c # WiFi 连接/热点封装实现
├── wifi_connecter.h # 封装接口头文件
├── BUILD.gn # GN 编译配置
├── README_zh.md # 案例简要说明
└── 实验手册.md # 本实验手册
AP 模块执行流程:
系统启动
│
▼
WifiHotspotDemo() ← SYS_RUN 注册,系统启动时自动执行
│
▼
osThreadNew(WifiHotspotTask) ← 创建热点任务线程
│
▼
WifiHotspotTask()
└── StartHotspot() ← 配置并启动 SoftAP + DHCP 服务器
├── wifi_softap_enable()
├── netifapi_netif_set_addr()
└── netifapi_dhcps_start()
STA 模块执行流程:
系统启动
│
▼
WifiConnectDemo() ← SYS_RUN 注册,系统启动时自动执行
│
▼
osThreadNew(WifiConnectTask) ← 创建连接任务线程
│
▼
WifiConnectTask()
├── ConnectToHotspot() ← 扫描、连接、DHCP 获取 IP
├── 60 秒倒计时(osDelay) ← 每秒打印剩余时间
└── DisconnectWithHotspot() ← 断开连接
3.2、源文件说明
| 文件 | 说明 |
|---|---|
wifi_connect_example_AP.c |
AP 热点示例,创建 WifiHotspotTask 线程启动热点 |
wifi_connect_example_STA.c |
STA 连接示例,创建 WifiConnectTask 线程连接热点并倒计时断开 |
wifi_connecter.c |
核心封装,实现 StartHotspot、ConnectToHotspot、DisconnectWithHotspot |
wifi_connecter.h |
封装接口声明 |
BUILD.gn |
编译配置,通过注释切换 AP/STA 源文件 |
3.3、关键代码分析
(1)AP 模块 — 热点配置参数
#define SSID "HiSpark_AP"
#define KEY "123456789"
#define WIFI_SEC_TYPE_PSK 2
#define CHANNEL 7
(2)AP 模块 — WifiHotspotTask 线程
热点线程直接调用 StartHotspot() 启动热点,并通过串口打印结果:
static void WifiHotspotTask(void)
{
if (StartHotspot(SSID, KEY, WIFI_SEC_TYPE_PSK, CHANNEL) != 0)
{
printf("StartHotspot failed!\n");
}
else
{
printf("StartHotspot success!\n");
}
}
(3)AP 模块 — 系统入口
static void WifiHotspotDemo(void)
{
osThreadAttr_t attr;
attr.name = "WifiHotspotTask";
attr.stack_size = 0x1000;
attr.priority = osPriorityNormal;
if (osThreadNew(WifiHotspotTask, NULL, &attr) == NULL)
{
printf("[WifiHotspotDemo] Falied to create WifiHotspotTask!\n");
}
}
SYS_RUN(WifiHotspotDemo);
(4)STA 模块 — WifiConnectTask 线程
连接线程完成"连接 → 倒计时保持 → 断开"的完整流程:
static void WifiConnectTask(void)
{
int timeout = 60;
if (ConnectToHotspot(SSID, KEY) != 0)
{
printf("Connect to AP failed!\n");
}
else
{
printf("Connect to AP success!\n");
}
while (timeout--)
{
printf("After %d seconds I will disconnect with AP!\r\n", timeout);
osDelay(100); // 100 ticks × 10 ms = 1 秒
}
DisconnectWithHotspot();
}
(5)封装层 — StartHotspot 核心逻辑
StartHotspot() 完成 SoftAP 启用与 DHCP 服务器配置:
errcode_t StartHotspot(char *ssid, char *key, wifi_security_enum security_type, uint8_t channel_num)
{
char ifname[] = "ap0";
ip4_addr_t st_ipaddr, st_netmask, st_gw;
softap_config_stru hapd_conf = {0};
IP4_ADDR(&st_ipaddr, 192, 168, 43, 1); // AP IP
IP4_ADDR(&st_netmask, 255, 255, 255, 0);
IP4_ADDR(&st_gw, 192, 168, 43, 2); // 网关
// 配置热点参数
memcpy_s(hapd_conf.ssid, sizeof(hapd_conf.ssid), ssid, strlen(ssid));
memcpy_s(hapd_conf.pre_shared_key, WIFI_MAX_KEY_LEN, key, WIFI_MAX_KEY_LEN);
hapd_conf.security_type = security_type;
hapd_conf.channel_num = channel_num;
// 启用 SoftAP(失败则重试)
while (wifi_softap_enable(&hapd_conf) != ERRCODE_SUCC) {
printf("Hotspot enable fail\r\n");
osal_msleep(100);
}
// 配置网络地址并启动 DHCP 服务器
netif_p = netif_find(ifname);
netifapi_netif_set_addr(netif_p, &st_ipaddr, &st_netmask, &st_gw);
netifapi_dhcps_start(netif_p, NULL, 0);
printf("wifi init succ.\r\n");
return ERRCODE_SUCC;
}
(6)封装层 — ConnectToHotspot 核心逻辑
ConnectToHotspot() 实现完整的 STA 连接流程:
errcode_t ConnectToHotspot(char *ssid, char *key)
{
// 1. 启用 STA 模式
while (wifi_sta_enable() != ERRCODE_SUCC) { ... }
// 2. 循环扫描 → 匹配 SSID → 连接
while (a) {
wifi_sta_scan();
wifi_register_event_cb(&wifi_event_cb);
get_match_network(ssid, key, &expected_bss); // 从扫描结果中匹配目标 AP
wifi_sta_connect(&expected_bss);
// 轮询等待连接成功 ...
}
// 3. DHCP 获取 IP
g_iface = netifapi_netif_find("wlan0");
netifapi_dhcp_start(g_iface);
// 等待 DHCP 绑定并获取 IP 地址 ...
printf("Connect success.\r\n");
return ERRCODE_SUCC;
}
(7)封装层 — get_match_network 扫描匹配
从扫描结果中按 SSID 字符串精确匹配目标热点,并复制 BSSID、加密类型和密码:
errcode_t get_match_network(char *expected_ssid, char *key, wifi_sta_config_stru *expected_bss)
{
wifi_sta_get_scan_info(result, &num); // 获取扫描结果
for (bss_index = 0; bss_index < num; bss_index++) {
if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) {
if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) {
break; // 找到目标 AP
}
}
}
// 复制 SSID、BSSID、加密类型、密码到连接配置结构体
expected_bss->ip_type = DHCP;
return ERRCODE_SUCC;
}
(8)BUILD.gn — AP/STA 切换
编译时通过注释切换 AP 或 STA 源文件,同一时刻只能编译其中一个:
static_library("wifi_connect_example") {
sources = [
"wifi_connecter.c",
#"wifi_connect_example_STA.c", // STA 模式(注释掉)
"wifi_connect_example_AP.c" // AP 模式(当前启用)
]
// ...
}
3.4、程序执行流程
4、编译步骤
本实验需要分别编译 AP 固件和 STA 固件,烧录到两块开发板。以下步骤只需在首次编译时完成 4.1~4.3 的配置注册。
4.1、确认案例目录
确认案例已位于 OpenHarmony 源码目录下:
applications/sample/wifi-iot/app/c1_wifi_connect/
├── wifi_connect_example_AP.c
├── wifi_connect_example_STA.c
├── wifi_connecter.c
├── wifi_connecter.h
├── BUILD.gn
└── 实验手册.md
若从外部复制,请将 c1_wifi_connect 目录放到上述 app/ 路径下。
4.2、修改 BUILD.gn(注册编译组件)
编辑 applications/sample/wifi-iot/app/BUILD.gn,在 features 列表中添加本案例:
lite_component("app") {
features = [
"startup",
"c1_wifi_connect:wifi_connect_example", // 添加此行
]
}
4.3、修改 SDK 配置文件
步骤 1:编辑 device/soc/hisilicon/ws63v100/sdk/build/config/target_config/ws63/config.py
找到 'ws63-liteos-app' 配置段,在其 'ram_component' 列表中添加:
"wifi_connect_example"
步骤 2:编辑 device/soc/hisilicon/ws63v100/sdk/libs_url/ws63/cmake/ohos.cmake
找到 "ws63-liteos-app" 对应的 set(COMPONENT_LIST 部分,添加:
"wifi_connect_example"
4.4、编译 AP 固件(开发板 A)
编辑 applications/sample/wifi-iot/app/c1_wifi_connect/BUILD.gn,确保 sources 中启用 AP 源文件:
sources = [
"wifi_connecter.c",
#"wifi_connect_example_STA.c",
"wifi_connect_example_AP.c"
]
在 OpenHarmony 源码根目录下执行编译:
rm -rf out
hb set -root .
# 通过上下方向键选择 ws63 对应的编译分支(如 nearlink_dk_3863 / ws63-liteos-app)
hb build -f
编译成功后,将固件烧录到 开发板 A(作为 AP 热点端)。
4.5、编译 STA 固件(开发板 B)
编辑 applications/sample/wifi-iot/app/c1_wifi_connect/BUILD.gn,切换为 STA 源文件:
sources = [
"wifi_connecter.c",
"wifi_connect_example_STA.c",
#"wifi_connect_example_AP.c"
]
重新编译:
rm -rf out
hb set -root .
hb build -f
编译成功后,将固件烧录到 开发板 B(作为 STA 连接端)。
4.6、烧录固件
使用开发板配套的烧录工具,将编译生成的固件分别烧写到两块 LZ3863-星闪开发板。具体烧录步骤请参考开发板用户手册。
5、运行结果
5.1、硬件准备
- 将 开发板 A(AP 固件)上电或复位,等待热点启动;
- 将 开发板 B(STA 固件)上电或复位,开始扫描并连接热点;
- 两块开发板分别通过 USB 连接 PC,打开串口助手查看日志(波特率 115200,8N1)。
建议:先启动 AP 端开发板,确认热点创建成功后再启动 STA 端,以提高首次连接成功率。
5.2、串口配置
| 参数 | 值 |
|---|---|
| 波特率 | 115200 |
| 数据位 | 8 |
| 停止位 | 1 |
| 校验位 | 无 |
| 流控 | 无 |
5.3、AP 端预期输出(开发板 A)
烧录 AP 固件并复位后,串口助手可观察到:
StartHotspot success!
wifi init succ.
表示热点 HiSpark_AP 已成功创建,DHCP 服务器已启动,等待 STA 设备连接。
5.4、STA 端预期输出(开发板 B)
烧录 STA 固件并复位后,串口助手可观察到完整的连接过程:
Start Scan !
[WIFI_STA_SAMPLE] Scan done!.
STA try connect.
[WIFI_STA_SAMPLE] Connect succ!.
STA DHCP start.
STA DHCP bound success.
STA IP 192.168.43.x
Connect success.
Connect to AP success!
After 59 seconds I will disconnect with AP!
After 58 seconds I will disconnect with AP!
...
After 1 seconds I will disconnect with AP!
After 0 seconds I will disconnect with AP!
netifapi_dhcp_stop: 0
Disconnect: 0
其中:
Start Scan !/Scan done!表示热点扫描完成;STA try connect./Connect succ!表示与 AP 关联成功;STA IP 192.168.43.x表示通过 DHCP 获取到 IP 地址;Connect to AP success!表示应用层确认连接成功;After N seconds...为 60 秒倒计时日志;Disconnect: 0表示断开连接成功。
5.5、结果分析
| 现象 | 说明 |
|---|---|
AP 端输出 StartHotspot success! |
SoftAP 热点创建成功 |
AP 端输出 wifi init succ. |
DHCP 服务器启动成功 |
STA 端输出 Scan done! |
周围热点扫描完成 |
STA 端输出 Connect succ! |
与目标 AP 无线关联成功 |
STA 端输出 STA IP 192.168.43.x |
DHCP 分配 IP 成功,网络层连通 |
| STA 端倒计时 60 秒后断开 | DisconnectWithHotspot() 正常执行 |
STA 端反复 Can not find AP |
AP 端未启动或 SSID/密码不匹配 |
STA 端 Connect to AP failed! |
连接流程异常,检查密码与加密类型 |
5.6、常见问题排查
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| STA 扫描不到 AP | AP 端未启动或距离过远 | 先启动 AP 端,两块板靠近放置 |
STA 反复 Can not find AP |
SSID 或密码不一致 | 确认两端 SSID/KEY 宏定义完全相同 |
| 关联成功但无 IP | DHCP 服务器未启动 | 检查 AP 端是否输出 wifi init succ. |
AP 端 StartHotspot failed! |
WiFi 驱动初始化异常 | 重新烧录固件,确认 config.py 已添加组件 |
编译报错找不到 wifi_connect_example |
BUILD.gn 或 config.py 未正确修改 | 逐步核对 4.2、4.3 节的配置项 |
| 两块板同时烧录了相同固件 | BUILD.gn 未切换 AP/STA 源文件 | 按 4.4、4.5 节分别编译烧录 |
| 倒计时期间连接中断 | 信号干扰或距离过远 | 缩短两块板距离,避开强干扰源 |
6、实验扩展
完成基本实验后,可尝试以下扩展练习:
- 修改热点参数:更改
SSID、KEY、CHANNEL宏定义,观察 STA 端是否需要同步修改才能连接; - 修改保持时间:将 STA 模块中
timeout = 60改为其他值,调整连接保持时长; - 手机验证热点:AP 固件烧录后,用手机搜索
HiSpark_AP热点并连接,验证热点可用性; - 连接外部路由器:修改 STA 模块的
SSID/KEY为家中路由器参数,实现开发板上网; - 静态 IP 配置:将
expected_bss->ip_type从DHCP改为静态 IP,理解 DHCP 与静态配置的区别; - 添加重连机制:在
DisconnectWithHotspot()后增加自动重新连接逻辑,实现断线重连; - 结合 TCP/UDP 实验:在 WiFi 连接成功后,配合后续网络通信案例实现数据收发。
更多推荐




所有评论(0)