简介
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。以下简述几个关键的概念:
图1
接口介绍
函数列表:
下表为PWM接口相关结构体类型。
结构体类型表:
类型 | 简要描述 |
aw_pwm_config_t | PWM配置参数结构体 |
aw_pwm_config_frac_t | PWM配置参数结构体(分数形式),用分数表示,更精确 |
1. aw_pwm_config_t
typedef struct {
uint32_t duty_ns;
uint32_t period_ns;
uint32_t is_inverse;
} aw_pwm_config_t;
成员详解:
is_inverse:输出波形是否反相,0表示不反相。
2. aw_pwm_config_frac
typedef struct aw_pwm_config_frac {
uint32_t duty_numerator;
uint32_t duty_denominator;
uint32_t period_numerator;
uint32_t period_denominator;
uint32_t is_inverse;
} aw_pwm_config_frac_t;
PWM配置参数结构体(分数形式),用分数表示,更精确。
duty_numerator:PWM周期中高电平的有效时间分子部分。
duty_denominator:PWM周期中高电平的有效时间分母部分。
period_numerator:PWM周期分子部分。
period_denominator:PWM周期分母部分。
is_inverse:PWM输出波形输出是否反向,0:不反向,1:反向。
使用样例
AWorksLP SDK相关使用请参考《AWorksLP SDK快速入门(MR6450)——开箱体验》一文,本文不在赘述。
/**
* \brief PWM演示例程入口
* \return 无
*/
aw_local void* __task_handle (void *arg)
{
uint32_t period1 = 2000000; /* (ns) */
uint32_t period2 = 1000000; /* (ns) */
int fd;
int ret;
aw_pwm_config_t pwm_config;
aw_kprintf("\nPWM demo testing...\n");
fd = aw_open(CONFIG_DEMO_PWM_DEVICE_NAME, AW_O_RDWR, 0);
if(fd < 0){
aw_kprintf("pwm open failed \r\n");
aw_close(fd);
return 0;
}
ret = aw_pwm_config_get(fd, &pwm_config);
/* period 配置不可以为0
* duty配置为0,这时可以配置成功:输出一直为低
* duty配置为peroid,占空比为100%,也可配置成功:输出一直为高
* PWM正在进行输出,不可配置 */
pwm_config.duty_ns = period1 / 2;
pwm_config.is_inverse = 0;
pwm_config.period_ns = period1;
aw_pwm_config_set(fd, &pwm_config);
while(1) {
/* 配置 PWM 的有效时间(高电平时间)50% ,周期 period1*/
aw_pwm_config_set(fd, &pwm_config);
aw_pwm_enable(fd); /* 使能通道 */
aw_mdelay(250);
aw_pwm_disable(fd); /* 禁能通道 */
aw_mdelay(250);
/* 输出五个周期pwm波*/
aw_pwm_accurate_output(fd, 5);
/* 配置 PWM 的有效时间(高电平时间)2% ,周期 period1*/
pwm_config.duty_ns = period1 / 50;
aw_pwm_config_set(fd, &pwm_config);
aw_pwm_enable(fd); /* 使能通道 */
aw_mdelay(250);
aw_pwm_disable(fd); /* 禁能通道 */
aw_mdelay(250);
pwm_config.duty_ns = period2 / 2;
pwm_config.period_ns = period2;
/* 配置 PWM 的有效时间(高电平时间)50% ,周期 period2*/
aw_pwm_config_set(fd, &pwm_config);
aw_pwm_enable(fd); /* 使能通道 */
aw_mdelay(250);
aw_pwm_disable(fd); /* 禁能通道 */
aw_mdelay(250);
/* 配置 PWM 的有效时间(高电平时间)2% ,周期 period2*/
pwm_config.duty_ns = period2 / 50;
aw_pwm_config_set(fd, &pwm_config);
aw_pwm_enable(fd); /* 使能通道 */
aw_mdelay(250);
aw_pwm_disable(fd); /* 禁能通道 */
aw_mdelay(250);
pwm_config.duty_ns = period1 / 2;
pwm_config.period_ns = period1;
}
return 0;
}
图2 pwm排针
上述代码中使用aw_pwm_config_get接口获取PWM当前的配置信息,PWM周期中高电平的有效时间为1000000ns,PWM周期为2000000ns,也就是设置PWM的占空比为50%。使用aw_pwm_config_set接口设置PWM。使用aw_pwm_enable接口使能PWM,使用aw_pwm_disable接口关闭PWM,使用aw_pwm_accurate_output接口输出任意个PWM波。
图3 占空比50%,周期2ms
图4 占空比2%,周期2ms
图5 占空比50%,周期1ms
图6 占空比2%,周期1ms
/**
* \brief 建立蜂鸣器例程入口
* \return 无
*/
aw_local void* __task_handle (void *arg)
{
int fd;
fd = aw_open("/dev/Buzzer", AW_O_RDWR, 0);
if(fd < 0){
aw_kprintf("Buzzer open failed \r\n");
aw_close(fd);
return 0;
}
while(1) {
/* 强度调节设备驱动无源蜂鸣器 */
aw_buzzer_loud_set(fd, 80); /* 设置蜂鸣器鸣叫强度 */
aw_buzzer_beep(fd, 500); /* 启动蜂鸣器延时500ms */
/* GPIO驱动直流蜂鸣器 */
aw_buzzer_loud_set(fd, 50); /* 设置蜂鸣器鸣叫强度 */
aw_buzzer_on(fd); /* 启动蜂鸣器 */
aw_mdelay(500); /* 延时500ms */
aw_buzzer_off(fd); /* 关闭蜂鸣器 */
aw_mdelay(500); /* 延时500ms */
}
aw_close(fd);
return 0;
}
蜂鸣器在开发板上的位置如图7所示。
图7 蜂鸣器位置
蜂鸣器引脚所对应的PWM通道为pwm3_chan1,如下图所示。
图8 蜂鸣器对应引脚
图9 PWM对应引脚
图10 蜂鸣器对应的PWM通道
更多往期文章,请点击“ 阅读原文 ”。