# PWM ## 概述 PWM是脉冲宽度调制(Pulse Width Modulation)的缩写,是一种对模拟信号电平进行数字编码并将其转换为脉冲的技术。常用于马达控制、背光亮度调节等。 PWM接口定义了操作PWM设备的通用方法集合,包括: - PWM设备句柄获取和释放。 - PWM周期、占空比、极性的设置。 - PWM使能和关闭。 - PWM配置信息的获取和设置。 ### PwmConfig结构体 **表1** PwmConfig结构体介绍 | 名称 | 描述 | | -------- | -------- | | duty | 占空时间,以纳秒为单位。 | | period | PWM周期,以纳秒为单位。 | | number | 要生成的方波数:
- 正值:表示将生成指定数量的方波
- 0:表示方波将不断产生 | | polarity | 极性:正极性/反极性。 | | status | 状态:启用状态/禁用状态。 | ## 接口说明 **表2** PWM驱动API接口功能介绍 | 功能分类 | 接口描述 | | -------- | -------- | | PWM句柄操作 | - PwmOpen:获取PWM设备驱动句柄
- PwmClose:释放PWM设备驱动句柄 | | 使能/禁用PWM | - PwmEnable:使能PWM
- PwmDisable:禁用PWM | | PWM配置操作 | - PwmSetPeriod:设置PWM周期
- PwmSetDuty:设置PWM占空时间
- PwmSetPolarity:设置PWM极性 | | 设置/获取PWM配置信息 | - PwmSetConfig:设置PWM设备参数
- PwmGetConfig:获取PWM设备参数 | > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 ## 使用指导 ### 使用流程 使用PWM的一般流程如下图所示。 **图1** PWM使用流程图 ![image](figures/PWM设备使用流程图.png "PWM设备使用流程图") ### 获取PWM设备句柄 在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。 ``` DevHandle PwmOpen(uint32_t num); ``` **表3** PwmOpen参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | num | PWM设备编号 | | **返回值** | **返回值描述** | | handle | 获取成功,返回PWM设备句柄 | | NULL | 获取失败 | 假设系统中的PWM设备号为0,获取该PWM设备句柄的示例如下: ``` uint32_t num = 0; /* PWM设备号 */ DevHandle handle = NULL; /* 获取PWM设备句柄 */ handle = PwmOpen(num); if (handle == NULL) { /* 错误处理 */ } ``` ### 销毁PWM设备句柄 关闭PWM设备,系统释放对应的资源。 ``` voidPwmClose(DevHandle handle); ``` **表4** PwmClose参数描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | ``` /* 销毁PWM设备句柄 */ PwmClose(handle); ``` ### 使能 启用PWM设备。 ``` int32_t PwmEnable(DevHandle handle); ``` **表5** PwmEnable参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | **返回值** | **返回值描述** | | 0 | 使能成功 | | 负数 | 使能失败 | ``` int32_t ret; /*启用PWM设备*/ ret = PwmEnable(handle); if (ret != 0) { /*错误处理*/ } ``` ### 禁用 禁用PWM设备。 ``` int32_t PwmDisable(DevHandle handle); ``` **表6** PwmDisable参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | **返回值** | **返回值描述** | | 0 | 禁用成功 | | 负数 | 禁用失败 | ``` int32_t ret; /* 禁用PWM设备 */ ret = PwmDisable(handle); if (ret != 0) { /* 错误处理 */ } ``` ### 设置PWM设备周期 设置PWM设备周期。 ``` int32_t PwmSetPeriod(DevHandle handle, uint32_t period); ``` **表7** PwmSetPeriod参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | period | 要设置的周期,单位为纳秒 | | **返回值** | **返回值描述** | | 0 | 设置成功 | | 负数 | 设置失败 | ``` int32_t ret; /* 设置周期为50000000纳秒 */ ret = PwmSetPeriod(handle, 50000000); if (ret != 0) { /*错误处理*/ } ``` ### 设置设备占空时间 设置PWM设备占空时间。 ``` int32_t PwmSetDuty(DevHandle handle, uint32_t duty); ``` **表8** PwmSetDuty参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | duty | 要设置的占空时间,单位为纳秒 | | **返回值** | **返回值描述** | | 0 | 设置成功 | | 负数 | 设置失败 | ``` int32_t ret; /* 设置占空时间为25000000纳秒 */ ret = PwmSetDuty(handle, 25000000); if (ret != 0) { /* 错误处理 */ } ``` ### 设置PWM设备极性 设置PWM设备极性。 ``` int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity); ``` **表9** PwmSetPolarity参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | polarity | 要设置的极性,正/反 | | **返回值** | **返回值描述** | | 0 | 设置成功 | | 负数 | 设置失败 | ``` int32_t ret; /* 设置极性为反 */ ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY); if (ret != 0) { /* 错误处理 */ } ``` ### 设置PWM设备参数 设置PWM设备参数。 ``` int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config); ``` **表10** PwmSetConfig参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | \*config | 参数指针 | | **返回值** | **返回值描述** | | 0 | 设置成功 | | 负数 | 设置失败 | ``` int32_t ret; struct PwmConfig pcfg; pcfg.duty = 25000000; /* 占空时间为25000000纳秒 */ pcfg.period = 50000000; /* 周期为50000000纳秒 */ pcfg.number = 0; /* 不断产生方波 */ pcfg.polarity = PWM_INVERTED_POLARITY; /* 极性为反 */ pcfg.status = PWM_ENABLE_STATUS; /* 运行状态为启用 */ /* 设置PWM设备参数 */ ret = PwmSetConfig(handle, &pcfg); if (ret != 0) { /* 错误处理 */ } ``` ### 获取PWM设备参数 获取PWM设备参数。 ``` int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config); ``` **表11** PwmGetConfig参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | \*config | 参数指针 | | **返回值** | **返回值描述** | | 0 | 获取成功 | | 负数 | 获取失败 | ``` int32_t ret; struct PwmConfig pcfg; /*获取PWM设备参数*/ ret = PwmGetConfig(handle, &pcfg); if (ret != 0) { /*错误处理*/ } ``` ## 使用实例 PWM设备完整的使用示例如下所示,首先获取PWM设备句柄,然后设置设备周期、占空时间、极性,获取设备参数。使能,设置设备参数,禁用,最后销毁PWM设备句柄。 ``` void PwmTestSample(void) { int32_t ret; uint32_t num; DevHandle handle = NULL; struct PwmConfig pcfg; pcfg.duty = 20000000; /* 占空时间为20000000纳秒 */ pcfg.period = 40000000; /* 周期为40000000纳秒 */ pcfg.number = 100; /* 生成100个方波 */ pcfg.polarity = PWM_NORMAL_POLARITY; /* 极性为正 */ pcfg.status = PWM_ENABLE_STATUS; /* 运行状态为启用 */ /* PWM设备编号,要填写实际平台上的编号 */ num = 1; /* 获取PWM设备句柄 */ handle = PwmOpen(num); if (handle == NULL) { HDF_LOGE("PwmOpen: failed!\n"); return; } /* 设置周期为50000000纳秒 */ ret = PwmSetPeriod(handle, 50000000); if (ret != 0) { HDF_LOGE("PwmSetPeriod: failed, ret %d\n", ret); goto _ERR; } /* 设置占空时间为25000000纳秒 */ ret = PwmSetDuty(handle, 25000000); if (ret != 0) { HDF_LOGE("PwmSetDuty: failed, ret %d\n", ret); goto _ERR; } /* 设置极性为反 */ ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY); if (ret != 0) { HDF_LOGE("PwmSetPolarity: failed, ret %d\n", ret); goto _ERR; } /* 获取PWM设备参数 */ ret = PwmGetConfig(handle, &pcfg); if (ret != 0) { HDF_LOGE("PwmGetConfig: failed, ret %d\n", ret); goto _ERR; } /* 启用PWM设备 */ ret = PwmEnable(handle); if (ret != 0) { HDF_LOGE("PwmEnable: failed, ret %d\n", ret); goto _ERR; } /* 设置PWM设备参数 */ ret = PwmSetConfig(handle, &pcfg); if (ret != 0) { HDF_LOGE("PwmSetConfig: failed, ret %d\n", ret); goto _ERR; } /* 禁用PWM设备 */ ret = PwmDisable(handle); if (ret != 0) { HDF_LOGE("PwmDisable: failed, ret %d\n", ret); goto _ERR; } _ERR: /* 销毁PWM设备句柄 */ PwmClose(handle); } ```