##前提 开启pwm:CONFIG_PWM_SUPPORT = y

##第一步
找到厂家的例子
08_pwmled
##第2步:
app 下面 创建一个目录:pwmled 把厂家的pwm_led_demo.c copy 到新创建的目录下,同时 创建BUILD.gn文件
#第三步
修改app 下既有的BUILD.gn
第4步:
编译 烧录 测试
hb clean
hb build -f


别忘了按复位键

完整代码:
```c
/*
* Copyright (c) 2020, HiHope Community.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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"
#include "hi_io.h"
#define RED_LED_PIN_NAME 10
#define RED_LED_PIN_FUNCTION WIFI_IOT_IO_FUNC_GPIO_10_GPIO
#define RESOLUTION 4096
#define PWM_FREQ_DIVITION 64000
static void PWMLedDemoTask(void *arg)
{
(void)arg;
//炫彩灯板的红灯
hi_io_set_func(10, 5);
IoTPwmInit(1);
while (1) {
// use PWM control RED LED brightness
for (int i = 1; i <= RESOLUTION; i *= 2) {
IoTPwmStart(1, i, PWM_FREQ_DIVITION);
usleep(250000);
IoTPwmStop(1);
}
}
}
static void PWMLedDemo(void)
{
osThreadAttr_t attr;
// set Red LED pin to GPIO function
IoTGpioInit(10);
attr.name = "PWMLedDemoTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 4096;
attr.priority = osPriorityNormal;
if (osThreadNew(PWMLedDemoTask, NULL, &attr) == NULL) {
printf("[ColorfulLightDemo] Falied to create PWMLedDemoTask!\n");
}
}
APP_FEATURE_INIT(PWMLedDemo);
这份代码是基于鸿蒙操作系统(OHOS) 开发的物联网应用程序,核心功能是通过 PWM(脉冲宽度调制) 技术控制LED灯的亮度,实现“阶梯式渐亮”效果。以下是对代码的逐部分解析:
一、代码整体结构
代码遵循鸿蒙应用开发的标准框架,分为:
1. 版权声明与开源许可
2. 头文件引用
3. 宏定义(硬件参数配置)
4. 核心任务函数(PWM控制逻辑)
5. 任务初始化函数(创建RTOS任务)
6. 应用入口(鸿蒙应用启动触发点)
二、逐段代码解析
1. 版权声明与开源许可
/*
* Copyright (c) 2020, HiHope Community.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* (省略具体许可条款)
*/
- 作用:采用类似BSD的开源许可协议,明确代码的使用、修改、分发规则,保护版权方和使用者的合法权益,允许开源商用,但需保留版权声明和免责条款。
2. 头文件引用
#include <stdio.h> // 标准输入输出(如printf)
#include <unistd.h> // 提供usleep等系统调用(用于延时)
#include "ohos_init.h" // 鸿蒙系统初始化接口(如APP_FEATURE_INIT)
#include "cmsis_os2.h" // CMSIS-RTOS v2 接口(任务创建、调度等)
#include "iot_gpio.h" // 物联网GPIO硬件控制接口(引脚初始化)
#include "iot_pwm.h" // 物联网PWM硬件控制接口(脉冲宽度调制)
#include "iot_errno.h" // 物联网模块错误码定义(此处未直接使用)
#include "hi_io.h" // 海思IO口功能配置接口(设置引脚为PWM模式)
- 头文件功能分工明确:
- 系统层:stdio.h/unistd.h(基础IO和延时)、cmsis_os2.h(RTOS任务管理)、ohos_init.h(鸿蒙应用初始化)。
- 硬件层:iot_gpio.h(GPIO引脚初始化)、iot_pwm.h(PWM控制)、hi_io.h(引脚功能切换,如GPIO→PWM)。
3. 宏定义(硬件参数配置)
#define RED_LED_PIN_NAME 10 // 红灯连接的GPIO引脚号(10号引脚)
#define RED_LED_PIN_FUNCTION WIFI_IOT_IO_FUNC_GPIO_10_GPIO // 引脚功能(GPIO模式,实际代码中改为PWM)
#define RESOLUTION 4096 // PWM分辨率(占空比的精度,4096级)
#define PWM_FREQ_DIVITION 64000 // PWM频率分频系数
- 关键参数解释:
- 引脚定义:RED_LED_PIN_NAME = 10 表示LED正极(或负极,取决于电路设计)连接到开发板的10号GPIO引脚。
- PWM分辨率(RESOLUTION):
PWM通过“高电平时间/周期”的占空比控制亮度,分辨率越高,亮度调节越细腻。4096级意味着占空比可从 1/4096(最暗)到 4096/4096(最亮)调节。
- PWM频率(由分频系数决定):
PWM频率 = 系统时钟频率 / 分频系数(假设开发板系统时钟为24MHz),则频率 = 24,000,000 / 64,000 = 375Hz。
选择375Hz是因为:频率过低会导致LED闪烁(人眼可见),频率过高会增加硬件功耗,375Hz兼顾“无闪烁”和“低功耗”。
4. 核心任务函数(PWM控制逻辑)
static void PWMLedDemoTask(void *arg)
{
(void)arg; // 忽略传入参数(RTOS任务函数要求的标准形参)
// 步骤1:配置10号引脚为PWM功能(替代GPIO模式)
hi_io_set_func(10, 5); // 5表示PWM功能(不同芯片功能编号可能不同,需查硬件手册)
// 步骤2:初始化1号PWM通道(与10号引脚绑定,硬件层面固定映射)
IoTPwmInit(1);
// 无限循环(RTOS任务通常为死循环,由系统调度器管理)
while (1) {
// 步骤3:通过PWM占空比递增,实现LED渐亮
for (int i = 1; i <= RESOLUTION; i *= 2) { // i以2的倍数递增(1→2→4→...→4096)
// 启动PWM:通道1,占空比 = i / RESOLUTION,分频系数64000
IoTPwmStart(1, i, PWM_FREQ_DIVITION);
usleep(250000); // 保持当前亮度250ms(0.25秒)
IoTPwmStop(1); // 停止PWM(LED熄灭,为下一级亮度做准备)
}
}
}
- 任务逻辑核心:通过指数级递增的占空比,实现LED“亮→灭→更亮→灭”的阶梯式渐变。
- 占空比变化:1/4096(微亮)→ 2/4096(稍亮)→ ... → 4096/4096(最亮),每次保持0.25秒后熄灭,循环往复。
- 为什么用i *= 2?指数递增让亮度变化更“有节奏感”,若改为线性递增(i++),会因分辨率过高导致亮度变化过于平缓,肉眼难以察觉。
5. 任务初始化函数(创建RTOS任务)
static void PWMLedDemo(void)
{
osThreadAttr_t attr; // RTOS任务属性结构体(配置任务名称、堆栈、优先级等)
// 步骤1:初始化10号GPIO引脚(即使后续改为PWM,先初始化GPIO是硬件操作惯例)
IoTGpioInit(10);
// 步骤2:配置任务属性
attr.name = "PWMLedDemoTask"; // 任务名称(调试时用于识别任务)
attr.attr_bits = 0U; // 任务属性标志(0表示默认)
attr.cb_mem = NULL; // 任务回调函数内存(NULL表示使用系统默认)
attr.cb_size = 0U; // 回调函数内存大小(0表示默认)
attr.stack_mem = NULL; // 任务堆栈内存(NULL表示使用系统动态分配)
attr.stack_size = 4096; // 任务堆栈大小(4KB,足够本简单任务使用)
attr.priority = osPriorityNormal; // 任务优先级(正常优先级,不抢占核心任务)
// 步骤3:创建RTOS任务,若失败则打印错误信息
if (osThreadNew(PWMLedDemoTask, NULL, &attr) == NULL) {
printf("[ColorfulLightDemo] Falied to create PWMLedDemoTask!\n");
}
}
- 作用:鸿蒙系统启动时,会调用此函数完成硬件初始化(GPIO引脚)和RTOS任务创建。
- 任务堆栈大小(4096字节):需根据任务复杂度调整,本任务仅含循环和PWM操作,4KB足够;若任务有复杂逻辑(如字符串处理、多函数调用),需增大堆栈。
- 任务优先级(osPriorityNormal):避免任务优先级过高导致系统核心任务(如调度、硬件驱动)被阻塞。
6. 应用入口(鸿蒙应用启动触发点)
APP_FEATURE_INIT(PWMLedDemo);
- 鸿蒙应用开发的标准入口宏:
系统启动时,会自动调用APP_FEATURE_INIT宏指定的函数(此处为PWMLedDemo),完成应用的初始化(创建任务、配置硬件)。
类似传统C语言的main函数,但鸿蒙基于RTOS,采用“任务驱动”而非“主函数线性执行”。
三、代码功能总结
1. 核心功能:通过PWM技术控制10号引脚连接的红色LED,实现“阶梯式渐亮→熄灭”的循环效果(亮度从微亮到最亮,每次变化间隔0.25秒)。
2. 技术原理:
- PWM(脉冲宽度调制):通过改变高电平时间占比(占空比),控制LED的平均电流,从而调节亮度(占空比越高,亮度越高)。
- RTOS任务:鸿蒙基于CMSIS-RTOS v2,任务独立运行,由系统调度器分配CPU资源,避免阻塞其他功能。
3. 硬件依赖:
- 开发板需支持鸿蒙系统(如华为Hi3861V100、润和鸿蒙开发板)。
- LED需正确连接到10号GPIO引脚(需根据硬件电路确认正负极接法,可能需串联限流电阻)。
四、潜在优化点
1. 移除冗余代码:
宏定义RED_LED_PIN_FUNCTION(GPIO模式)未实际使用(代码中通过hi_io_set_func将引脚设为PWM模式),可删除避免混淆。
2. 优化亮度渐变逻辑:
目前IoTPwmStop(1)会导致LED熄灭,若想实现“连续渐亮”(不熄灭),可删除IoTPwmStop,直接在循环中修改占空比(无需停止PWM)。
3. 增加参数灵活性:
将引脚号、PWM频率、渐变间隔等参数通过宏定义集中管理,方便适配不同硬件(如改为控制绿灯、调整渐变速度)。
4. 添加错误处理:
目前IoTPwmInit、IoTPwmStart未判断返回值(如初始化失败),可添加错误码检查(参考iot_errno.h),增强代码健壮性。

被折叠的 条评论
为什么被折叠?



