PWM

About 7 min

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所示。

图 1 PWM设备使用流程图

获取PWM设备句柄

在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。

DevHandle PwmOpen(uint32_t num);
1

表3 PwmOpen参数和返回值描述

参数 参数描述
num PWM设备编号
返回值 返回值描述
handle 获取成功返回PWM设备句柄
NULL 获取失败
uint32_t num = 0;             /* PWM设备号 */
DevHandle handle = NULL;

/* 获取PWM设备句柄 */
handle = PwmOpen(num);
if (handle  == NULL) {
    /* 错误处理 */
}
1
2
3
4
5
6
7
8

销毁PWM设备句柄

关闭PWM设备,系统释放对应的资源。

void PwmClose(DevHandle handle);
1

表4 PwmClose参数描述

参数 参数描述
handle PWM设备句柄
/* 销毁PWM设备句柄 */
PwmClose(handle);
1
2

使能

启用PWM设备。

int32_t PwmEnable(DevHandle handle);
1

表5 PwmEnable参数描述

参数 参数描述
handle PWM设备句柄
返回值 返回值描述
0 使能成功
负数 使能失败
int32_t ret;

/*启用PWM设备*/
ret = PwmEnable(handle);
if (ret != 0) {
	/*错误处理*/
}
1
2
3
4
5
6
7

禁用

禁用PWM设备。

int32_t PwmDisable(DevHandle handle);
1

表6 PwmDisable参数描述

参数 参数描述
handle PWM设备句柄
返回值 返回值描述
0 禁用成功
负数 禁用失败
int32_t ret;

/*禁用PWM设备*/
ret = PwmDisable(handle);
if (ret != 0) {
	/*错误处理*/
}
1
2
3
4
5
6
7

设置PWM设备周期

设置PWM设备周期。

int32_t PwmSetPeriod(DevHandle handle, uint32_t period);
1

表7 PwmSetPeriod参数描述

参数 参数描述
handle PWM设备句柄
period 要设置的周期,单位为纳秒
返回值 返回值描述
0 设置成功
负数 设置失败
int32_t ret;

/*设置周期为50000000纳秒*/
ret = PwmSetPeriod(handle, 50000000);
if (ret != 0) {
	/*错误处理*/
}
1
2
3
4
5
6
7

设置PWM设备占空时间

设置PWM设备占空时间。

int32_t PwmSetDuty(DevHandle handle, uint32_t duty);
1

表8 PwmSetDuty参数描述

参数 参数描述
handle PWM设备句柄
duty 要设置的占空时间,单位为纳秒
返回值 返回值描述
0 设置成功
负数 设置失败
int32_t ret;

/*设置占空时间为25000000纳秒*/
ret = PwmSetDuty(handle, 25000000);
if (ret != 0) {
	/*错误处理*/
}
1
2
3
4
5
6
7

设置PWM设备极性

设置PWM设备极性。

int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity);
1

表9 PwmSetPolarity参数描述

参数 参数描述
handle PWM设备句柄
polarity 要设置的极性,正/反
返回值 返回值描述
0 设置成功
负数 设置失败
int32_t ret;

/*设置极性为反*/
ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY);
if (ret != 0) {
	/*错误处理*/
}
1
2
3
4
5
6
7

设置PWM设备参数

设置PWM设备参数。

int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config);
1

表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) {
	/*错误处理*/
}
1
2
3
4
5
6
7
8
9
10
11
12
13

获取PWM设备参数

获取PWM设备参数。

int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config);
1

表11 PwmGetConfig参数描述

参数 参数描述
handle PWM设备句柄
*config 参数指针
返回值 返回值描述
0 获取成功
负数 获取失败
int32_t ret;
struct PwmConfig pcfg;

/*获取PWM设备参数*/
ret = PwmGetConfig(handle, &pcfg);
if (ret != 0) {
	/*错误处理*/
}
1
2
3
4
5
6
7
8

使用实例

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); 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76