4. Hi3861 PWM呼吸灯效果实现
任务说明
本案例在OpenHarmony南向设备上,通过PWM模块输出频率固定、占空比周期性变化的方波信号,驱动LED实现由暗渐亮再渐暗的呼吸灯效果。需要完成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亮度变化:
- LED应从最暗状态开始,约1.7秒内逐渐变亮至最亮;
- 随后约1.7秒内逐渐变暗回到最暗状态;
- 上述过程循环往复,形成平滑的呼吸效果。
判定标准:LED亮度连续无跳变,周期稳定在3~4秒之间,且最亮时无闪烁,即判定为通过。若LED恒亮或恒灭,检查GPIO2引脚连接及PWM初始化是否成功。