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设备参数 |
说明: PWM当前仅限内核态使用,不支持在用户态使用。
使用指导
使用流程
在操作系统启动过程中,驱动管理模块根据配置文件加载PWM驱动,PWM驱动会检测PWM器件并初始化驱动。
使用PWM设备的一般流程如图1所示。
获取PWM设备句柄
在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。
DevHandle PwmOpen(uint32_t num);
表3 PwmOpen参数和返回值描述
参数 | 参数描述 |
---|---|
num | PWM设备编号 |
返回值 | 返回值描述 |
handle | 获取成功返回PWM设备句柄 |
NULL | 获取失败 |
uint32_t num = 0; /* PWM设备号 */
DevHandle handle = NULL;
/* 获取PWM设备句柄 */
handle = PwmOpen(num);
if (handle == NULL) {
/* 错误处理 */
}
销毁PWM设备句柄
关闭PWM设备,系统释放对应的资源。
void PwmClose(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设备占空时间
设置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);
}