鸿蒙 6.0 单片机深度入门方案

  • 2026-05-06
    北京
  • 本文字数:6789 字

    阅读完需:约 22 分钟

一、鸿蒙 6.0 单片机开发概述

1.1 什么是 OpenHarmony 轻量系统

OpenHarmony 6.0 LTS(Long Term Support)是华为面向全场景智能终端设备推出的开源操作系统。作为国产操作系统的标杆之作,鸿蒙系统在嵌入式领域展现出独特的技术魅力。与传统 RTOS 相比,鸿蒙轻量系统不仅具备实时响应能力,更原生支持分布式架构,为物联网设备赋予了互联互通的基因。


轻量系统(LiteOS-M 内核)专为 MCU 类处理器设计,支持 ARM Cortex-M、RISC-V 等架构。系统最小内存需求仅 128KB,却能提供完整的设备管理能力。对于单片机开发者而言,这意味着可以在资源受限的芯片上运行功能完备的操作系统,告别裸机开发的种种局限。


轻量系统的典型应用场景:


  • 智能家居领域的连接类模组(如智能开关、传感器节点)

  • 工业领域的分布式数据采集终端

  • 穿戴类设备的低功耗协处理器

  • 智慧物流中的资产追踪标签

1.2 鸿蒙 6.0 开发架构解析


如上图所示,鸿蒙单片机开发采用经典的五层架构设计:


应用层 承载具体业务逻辑,开发者使用 C 语言编写控制程序。鸿蒙提供了标准化的设备能力接口,屏蔽了底层硬件差异,使得同一套代码可以在不同开发板上运行。


框架层 封装了分布式能力框架、设备管理框架等核心组件。开发者通过统一的 API 调用硬件功能,无需关心 GPIO 寄存器的具体地址配置。


系统服务层 提供安全服务、通信服务、数据管理等基础能力。这些服务经过华为多年技术积累,稳定性得到充分验证。


硬件抽象层(HAL) 是开发的核心区域。GPIO、I2C、SPI、UART、ADC 等外设驱动都在这一层实现。鸿蒙 6.0 引入的 HDF(HarmonyOS Driver Foundation)驱动框架,将驱动开发从"手写寄存器"带入"配置驱动"时代。


硬件层 包括 Hi3861、STM32F4 等主控芯片,以及各类传感器、执行器模块。

1.3 主流开发板选型指南


入门首选推荐 BearPi-HM Nano——板载高度集成的 Hi3861 WiFi SoC 芯片,配套完善的 E53 扩展接口生态,支持直接连接 OLED 屏幕、温湿度传感器、LED 等外设。最关键的是,这块开发板的资料最为丰富,社区活跃度高,遇到问题容易找到解决方案。



二、开发环境搭建

2.1 工具链概述


鸿蒙单片机开发需要配置两套环境:


Linux 编译服务器(或虚拟机):承担代码编译任务


  • Ubuntu 20.04 LTS(推荐)

  • Python 3.7+

  • SCons 3.0.4+ 构建系统

  • gcc_riscv32 交叉编译工具链(Hi3861 使用 RISC-V 架构)

  • GNU Make、Ninja 构建工具


Windows 工作台:负责代码编辑、烧录、调试


  • Visual Studio Code + DevEco Device Tool 插件

  • HiBurn 烧录工具

  • 串口调试助手(MobaXterm/PuTTY)

  • CH340 USB 转串口驱动

2.2 Linux 环境配置详解

# 1. 安装Python及依赖sudo apt-get updatesudo apt-get install python3.7 python3-setuptools python3-pip -ysudo pip3 install setuptools kconfiglib pycryptodome ecdsa six
# 2. 安装编译工具链sudo apt-get install scons build-essential git -y
# 3. 下载gcc_riscv32交叉编译器cd ~ && wget https://download.qcloud.com/wireless/openharmony/compiler/gcc_riscv32-linux-7.3.0.tar.xztar -xvf gcc_riscv32-linux-7.3.0.tar.xzexport PATH=~/gcc_riscv32/bin:$PATH
# 4. 验证工具链riscv32-unknown-elf-gcc -v# 应显示 gcc version 7.3.0
复制代码


实战心得:国内开发者经常遇到 gcc_riscv32 下载失败的问题。可以使用百度网盘镜像(搜索"鸿蒙 gcc_riscv32 网盘"),或从华为官方镜像站点获取。部分企业用户反映,使用代理或 VPN 下载速度会显著提升。

2.3 DevEco Device Tool 配置

DevEco Device Tool 是华为官方提供的 VS Code 插件,将编译、烧录、调试集成到统一界面:


  1. 从华为开发者联盟官网下载.deb 安装包

  2. VS Code 中依次点击"扩展" → "从 VSIX 安装"

  3. 重启 VS Code,左侧工具栏出现鸿蒙图标即表示安装成功


常见问题排查


  • 如果 VS Code 无法识别设备,检查 USB 线是否为数据线(部分充电线不支持数据传输)

  • 烧录时提示"设备未找到",需要安装 CH340 驱动

  • 编译报错"command not found",检查 PATH 环境变量是否配置正确



三、项目创建与代码结构

3.1 源码下载与工程初始化

# 使用repo工具同步源码(需先配置git)mkdir ~/harmony && cd ~/harmonyrepo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verifyrepo sync -crepo forall -c 'git lfs pull'
# 进入源码目录cd ~/harmony
复制代码

3.2 目录结构详解

device/                          # 芯片与板级适配├── board/                       # 厂商开发板代码│   └── bearpi/                  # 小熊派适配│       └── hm_nano/├── soc/                         # SoC芯片适配│   └── hisilicon/│       └── hi3861/vendor/                          # 产品配置applications/                    # 应用程序    └── sample/                  # 示例代码        └── wifi_iot/            ├── app/BUILD.gn     # 应用构建配置            └── src/             # 源代码目录
复制代码


关键文件说明


  • BUILD.gn:GN 构建脚本,定义模块依赖和编译规则

  • config.json:产品配置文件,定义外设列表

  • hi3861_adapter.h:硬件适配层头文件

3.3 新建第一个工程

applications/sample/wifi_iot/app目录下创建新项目:


mkdir my_first_projectcd my_first_project
复制代码


创建hello_world.c


#include <stdio.h>#include "ohos_init.h"#include "kernel/os/os.h"
static void HelloTask(void *arg){ (void)arg; printf("Hello, HarmonyOS!\r\n"); int count = 0; while (1) { printf("Count: %d\r\n", count++); osDelay(100); // 延时100个Tick }}
APP_FEATURE_INIT(HelloTask); // 模块初始化宏
复制代码


创建对应的BUILD.gn


import("//build/lite/gn_rust.gni")import("//build/lite/ohos.gni")
ohos_executable("my_hello") { sources = [ "hello_world.c" ] include_dirs = [ "//utils/native/lite/include", "//kernel/liteos_m/components/libs/libc/include", ] deps = [ "//kernel/liteos_m:liteos_m", "//third_party/FreeBSD/libc:libc", ]}
复制代码



四、核心代码实战

4.1 GPIO 控制 LED 闪烁

LED 控制是单片机开发的"Hello World"。通过 GPIO 输出高低电平,实现 LED 的亮灭控制。


#include <stdio.h>#include <unistd.h>#include "ohos_gpio.h"#include "ohos_errno.h"#include "hi_io.h"#include "hi_gpio.h"
/* 定义LED连接的GPIO引脚 - BearPi-HM Nano默认GPIO09 */#define LED_GPIO_IDX 9
/** * GPIO初始化配置 */static void GpioLedInit(void){ // 1. 设置GPIO为输出模式 IoTGpioInit(LED_GPIO_IDX); IoTGpioSetDir(LED_GPIO_IDX, IOT_GPIO_DIR_OUT); // 2. 初始化默认关闭LED(高电平关闭,低电平点亮) IoTGpioSetOutputVal(LED_GPIO_IDX, IOT_GPIO_VALUE1);}
/** * LED控制任务 * 每500ms切换一次LED状态 */static void LedBlinkTask(void *arg){ (void)arg; GpioLedInit(); printf("[LED] Blink task started on GPIO%d\r\n", LED_GPIO_IDX); while (1) { // 点亮LED IoTGpioSetOutputVal(LED_GPIO_IDX, IOT_GPIO_VALUE0); printf("[LED] ON\r\n"); usleep(500000); // 延时500ms // 关闭LED IoTGpioSetOutputVal(LED_GPIO_IDX, IOT_GPIO_VALUE1); printf("[LED] OFF\r\n"); usleep(500000); }}
// 模块入口注册APP_FEATURE_INIT(LedBlinkTask);
复制代码


实战心得


  1. BearPi-HM Nano 的 LED 是共阳极设计,因此 GPIO 输出低电平时点亮

  2. 使用usleep()延时精度优于osDelay(),适合毫秒级精确控制

  3. 调试时可在串口输出状态信息,便于观察程序运行流程

4.2 ADC 按键检测

ADC(模数转换器)可以仅用少量 GPIO 实现多个按键检测。通过分压电阻网络,不同按键按下时产生不同的电压值。


#include <stdio.h>#include "ohos_adc.h"#include "hi_gpio.h"#include "hi_adc.h"
/* ADC通道定义 - 按键连接在GPIO11/ADC通道 */#define ADC_CHANNEL 1#define ADC_VREF_MV 1800 // 参考电压1.8V
/* 按键阈值定义(根据实际电路调整) */#define KEY_THRESHOLD_1 400 // 按键1按下电压约0.4V#define KEY_THRESHOLD_2 1000 // 按键2按下电压约1.0V#define KEY_THRESHOLD_3 1600 // 按键3按下电压约1.6V
/** * 读取ADC原始值 */static unsigned int ReadAdcValue(unsigned int channel){ unsigned int value = 0; // 配置ADC:采样10次取平均 if (HiAdcRead(channel, &value, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAUDRATE) != 0) { printf("[ADC] Read error!\r\n"); return 0; } return value;}
/** * 电压值转换为mV */static unsigned int GetVoltageMv(unsigned int adcValue){ // ADC分辨率为12位,满量程1800mV return (adcValue * ADC_VREF_MV) / 4095;}
/** * 按键检测任务 */static void AdcKeyTask(void *arg){ (void)arg; unsigned int lastKey = 0; printf("[ADC] Key detection task started\r\n"); while (1) { unsigned int adcValue = ReadAdcValue(ADC_CHANNEL); unsigned int voltage = GetVoltageMv(adcValue); unsigned int keyPressed = 0; if (voltage < KEY_THRESHOLD_1) { keyPressed = 1; } else if (voltage < KEY_THRESHOLD_2) { keyPressed = 2; } else if (voltage < KEY_THRESHOLD_3) { keyPressed = 3; } // 消抖处理:状态变化时才触发 if (keyPressed != lastKey) { if (keyPressed > 0) { printf("[ADC] Key%d pressed, voltage=%dmV, raw=%d\r\n", keyPressed, voltage, adcValue); } lastKey = keyPressed; } usleep(50000); // 50ms采样周期 }}
APP_FEATURE_INIT(AdcKeyTask);
复制代码


实战心得


  1. ADC 按键的关键是精确测量分压电阻值,计算各按键的特征电压

  2. 建议在电路设计时,各按键电压间隔大于 200mV,便于软件区分

  3. 消抖处理必不可少,否则一次按键可能被识别为多次

4.3 I2C 读取温湿度传感器

I2C 是单片机开发中最常用的传感器接口协议。以 SHT30 温湿度传感器为例:


#include <stdio.h>#include "ohos_i2c.h"#include "hi_i2c.h"
/* I2C配置 */#define I2C_IDX 0#define SHT30_ADDR 0x44 // SHT30传感器7位地址#define I2C_BAUDRATE 400000 // 400KHz高速模式
/* SHT30命令 */#define CMD_MEASURE 0x2C06 // 高精度测量命令
/** * I2C初始化 */static void Sht30I2cInit(void){ IoTI2cInit(I2C_IDX, I2C_BAUDRATE); printf("[I2C] Initialized I2C%d at %dHz\r\n", I2C_IDX, I2C_BAUDRATE);}
/** * 向SHT30写入命令 */static int Sht30WriteCommand(unsigned short cmd){ unsigned char data[2] = { (cmd >> 8) & 0xFF, cmd & 0xFF }; return IoTI2cWrite(I2C_IDX, SHT30_ADDR << 1, data, 2);}
/** * 从SHT30读取数据 */static int Sht30ReadData(unsigned char *buffer, int len){ return IoTI2cRead(I2C_IDX, SHT30_ADDR << 1, buffer, len);}
/** * 解析温度值 */static float ParseTemperature(unsigned char msb, unsigned char lsb){ // 温度计算公式:T = -45 + 175 * (raw / 65535) unsigned int raw = ((unsigned int)msb << 8) | lsb; return -45.0f + 175.0f * ((float)raw / 65535.0f);}
/** * 解析湿度值 */static float ParseHumidity(unsigned char msb, unsigned char lsb){ // 湿度计算公式:RH = 100 * (raw / 65535) unsigned int raw = ((unsigned int)msb << 8) | lsb; return 100.0f * ((float)raw / 65535.0f);}
/** * 温湿度读取任务 */static void Sht30Task(void *arg){ (void)arg; unsigned char recvData[6]; Sht30I2cInit(); printf("[SHT30] Temperature/Humidity sensor task started\r\n"); while (1) { // 发送测量命令 if (Sht30WriteCommand(CMD_MEASURE) == 0) { usleep(20000); // 等待测量完成 // 读取6字节数据 if (Sht30ReadData(recvData, 6) == 0) { float temp = ParseTemperature(recvData[0], recvData[1]); float humi = ParseHumidity(recvData[3], recvData[4]); printf("[SHT30] Temperature: %.2f°C, Humidity: %.2f%%\r\n", temp, humi); } else { printf("[SHT30] Read failed\r\n"); } } else { printf("[SHT30] Write command failed\r\n"); } sleep(2); // 每2秒读取一次 }}
APP_FEATURE_INIT(Sht30Task);
复制代码

4.4 UART 串口通信

UART 用于开发板与 PC 或其他设备的数据交互:


#include <stdio.h>#include "ohos_uart.h"#include "hi_uart.h"
/* UART配置 - 使用UART0,波特率115200 */#define UART_IDX 0#define UART_BAUDRATE 115200
/** * UART初始化配置 */static void UartInit(void){ // 配置UART参数 UartAttribute attr = { .baudRate = UART_BAUDRATE, .dataBits = 8, .stopBits = 1, .parity = 0, // 无校验 }; IoTUartInit(UART_IDX); IoTUartSetAttribute(UART_IDX, &attr); printf("[UART] Initialized UART%d at %d baud\r\n", UART_IDX, UART_BAUDRATE);}
/** * UART发送字符串 */static void UartSendString(const char *str){ unsigned int len = 0; while (str[len] != '\0') len++; IoTUartWrite(UART_IDX, (unsigned char *)str, len);}
/** * UART接收任务 */static void UartTask(void *arg){ (void)arg; unsigned char recvBuffer[256]; UartInit(); // 发送欢迎信息 UartSendString("\r\n=== HarmonyOS UART Demo ===\r\n"); UartSendString("Please send commands:\r\n"); while (1) { int len = IoTUartRead(UART_IDX, recvBuffer, sizeof(recvBuffer)); if (len > 0) { // 收到数据,原样回显 recvBuffer[len] = '\0'; printf("[UART] Received: %s\r\n", recvBuffer); // 回传确认 char response[64]; snprintf(response, sizeof(response), "[UART] Echo: %s\r\n", recvBuffer); UartSendString(response); } usleep(10000); // 10ms轮询间隔 }}
APP_FEATURE_INIT(UartTask);
复制代码



五、烧录与调试

5.1 编译固件

# 设置工具链环境变量export PATH=~/gcc_riscv32/bin:$PATHexport PATH=~/ninja:$PATH
# 进入源码目录cd ~/harmony
# 选择开发板hb set# 交互式选择:Select board → bearpi_hm_nano
# 编译hb build -f
复制代码


编译成功后,固件位于out/bearpi_hm_nano/目录:


  • Hi3861_demo_flash_tool.bin:烧录文件

  • Hi3861_demo.bin:运行文件

5.2 烧录流程


  1. 硬件连接:使用 USB Type-C 线连接开发板与 PC

  2. 进入烧录模式:按住复位键,松开后立即点击 HiBurn 的"开始烧录"按钮

  3. 选择固件:在 HiBurn 中选择编译生成的.bin文件

  4. 烧录进度:观察进度条,等待烧录完成

  5. 验证运行:打开串口工具(115200-8-N-1),查看系统启动日志


常见烧录问题


5.3 串口调试技巧

使用 MobaXterm 创建串口会话,连接到开发板:


# 查看串口输出[OHOS] boot succeed...[APP]  Hello HarmonyOS![LED]  Blink task started on GPIO9
复制代码


调试技巧


  • 在关键位置添加printf()日志输出

  • 使用assert()捕获异常状态

  • 设置合理的日志级别(DEBUG/INFO/WARN/ERROR)



六、进阶学习路径

6.1 能力提升路线

结语

鸿蒙 6.0 单片机开发为嵌入式工程师打开了新的大门。借助完善的驱动框架和分布式能力,开发者可以专注于业务逻辑实现,而不必深陷寄存器配置的泥潭。从 LED 闪烁到传感器采集,从 WiFi 连接到云端通信,每一步都是成长的印记。


愿每一位开发者都能在鸿蒙生态中找到属于自己的舞台,为国产操作系统生态贡献力量。


发布于: 2026-05-06阅读数: 152
用户头像

InfoQ签约作者 2018-11-30 加入

热爱生活,收藏美好,专注技术,持续成长

评论

发布
暂无评论