4. Hi3861 PWM呼吸灯效果实现

任务说明

本案例在OpenHarmony南向设备上,通过PWM模块输出频率固定、占空比周期性变化的方波信号,驱动LED实现由暗渐亮再渐暗的呼吸灯效果。需要完成PWM控制器初始化、占空比更新与延时控制三个核心环节。

硬件连接

Hi3861 开发板 PWM0 / GPIO2 GPIO2 220Ω LED GND PWM输出

将LED正极通过220Ω限流电阻连接至开发板GPIO2(PWM0通道),LED负极接GND。GPIO2在Hi3861上复用为PWM0输出引脚。

代码实现

新建pwm_breath.c文件,完整代码如下:


#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_pwm.h"
#include "iot_errno.h"

#define PWM_FREQ            1000    // 1kHz 频率
#define PWM_DUTY_MAX        90      // 最大占空比(%)
#define PWM_DUTY_MIN        5       // 最小占空比(%)
#define STEP_DELAY_US       20000   // 每步延时 20ms
#define DUTY_STEP           1       // 占空比步进值

static void *PwmBreathTask(void *arg)
{
    (void)arg;
    unsigned int duty = PWM_DUTY_MIN;
    int direction = 1;  // 1=渐亮, -1=渐暗

    // 初始化GPIO2为PWM功能
    IoTGpioInit(2);
    IoTGpioSetFunc(2, IOT_GPIO_FUNC_GPIO_2_PWM0_OUT);
    IoTPwmInit(0);

    while (1) {
        // 设置PWM0频率与占空比
        IoTPwmSetPeriod(0, PWM_FREQ);
        IoTPwmSetDuty(0, duty);

        // 更新占空比方向
        duty += direction * DUTY_STEP;
        if (duty >= PWM_DUTY_MAX) {
            duty = PWM_DUTY_MAX;
            direction = -1;
        } else if (duty <= PWM_DUTY_MIN) {
            duty = PWM_DUTY_MIN;
            direction = 1;
        }

        usleep(STEP_DELAY_US);
    }
    return NULL;
}

static void PwmBreathEntry(void)
{
    osThreadAttr_t attr = {0};
    attr.name = "PwmBreathTask";
    attr.stack_size = 4096;
    attr.priority = osPriorityNormal;

    osThreadNew(PwmBreathTask, NULL, &attr);
}

SYS_RUN(PwmBreathEntry);

代码说明

  • PWM初始化:IoTGpioSetFunc将GPIO2复用为PWM0输出引脚,IoTPwmInit启动PWM控制器。
  • 占空比控制:IoTPwmSetPeriod设置频率为1kHz,IoTPwmSetDuty设置占空比(5%~90%)。
  • 呼吸节奏:每20ms改变1%占空比,从5%渐增至90%再渐减,完成一个呼吸周期约3.4秒。

编译与烧录

将pwm_breath.c放入applications/sample/wifi-iot/app目录,在BUILD.gn中添加源文件引用,然后执行编译:


python build.py wifiiot

编译成功后,使用HiBurn工具将生成的Hi3861_wifiiot_app_allinone.bin烧录至开发板。

验证方法

烧录完成后,开发板自动运行程序。观察LED亮度变化:

  1. LED应从最暗状态开始,约1.7秒内逐渐变亮至最亮;
  2. 随后约1.7秒内逐渐变暗回到最暗状态;
  3. 上述过程循环往复,形成平滑的呼吸效果。

判定标准:LED亮度连续无跳变,周期稳定在3~4秒之间,且最亮时无闪烁,即判定为通过。若LED恒亮或恒灭,检查GPIO2引脚连接及PWM初始化是否成功。