一、PWM知识
1 PWM概念
PWM全称Pulse WidthModulation,脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。简单的说,使用PWM可以实现平时我们常用的电阻器调压,可以控制电灯亮度、电机转速、音量大小等所有想得到的调节功能。
简而言之,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
2 PWM重要参数
PWM的两个重要参数是周期(period)和占空比(duty),周期是表示一个脉冲宽度,单位为时间单位,如s;还有一个是频率,它与周期互为倒数,物理意义是指每秒钟信号从高电平到低电平再回到高电平的次数。占空比是指脉冲信号的通电时间与通电周期之比。
3 PWM的主要作用:
1)驱动电机,即通过pwm的脉冲,控制步进电机的转动,通过PWM的脉冲大小,控制伺服电机的转动。如航模中的控制信号大多是PWM信号,比如FUTABA,JR等舵机的控制都采用PWM方式。
2)控制电压,即很多电源内容的调节系统是通过它实现的。如充电器,通过调整PWM的占空比,从而控制充电电流。在调整充电电流前,电源先快速读取充电电流的大小,然后把设定的充电电流与实际读取到的充电电流进行比较,若实际电流偏小则向增加充电电流的方向调整PWM的占空比;若实际电流偏大则向减小充电电流的方向调整PWM的占空比。
3)调制信号,利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
4)等等
二 BBG(Beaglebone
Green)上的PWM
1 Beaglebone Green同Beaglebone Black一样,都是采用和TI公司的AM3358处理器,从AM335x Sitara Processors Technical Reference Manual中可得知,板上的PWM,属于PWMSS(Pulse-Width Modulation Subsystem )下的eHRPWM(Enhanced PWM
Module)下的功能,在AM335x中,有3个,每个信道(Channel)或模块(Module),又为为PWMA和PWMB,它们成对出现
2 在BBG上,同BBB一样,通过扩展插槽,引出了8个PWM引脚,如下图所示
三 控制PWM
1 启动PWM
1 )加载pwm测试模块
modprobe pwm_test
2) 加载amxx_pwm
echo am33xx_pwm >
/sys/devices/bone_capemgr.*/slots
3) 加载pwm
echo bone_pwm_P8_13 >
/sys/devices/bone_capemgr.*/slots
4 )查看加载情况
root@beaglebone:/sys/devices/ocp.2/pwm_test_P8_13.15# ls
driver duty modalias period
polarity power run subsystem uevent
PS:BBB板中,操作PWM用到duty(duty_ns)、period(period_ns)、polarity、run共四个参数,其中period就是频率参数(周期时间),duty为占空比,polarity为使能标志(1为使能,0为禁用),run 是执行命令(1为运行,0为关闭),period和duty的参数单位为纳秒(ns),1s=1000ms=1000000us=1000000000ns,所以period最大的取值范围为0—1000000000,而duty则取值0—period值之间
2 终端控制
1) 连接电路,将P8_13引脚连接发光二极管的正级(长线),二极管的另一端连接GND
2) 终端测试
echo
0 >
run (设置周期和占空比前,需关闭输出)
echo 1000000000(9) > period (设置周期为1s,period的单位为ns)
echo 500000000 >
duty (设置占空比为0.5,duty的值也为ns)
echo
1 >
polarity
echo 1
>run
3 软件编程
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEFAULT_PREFIX "/sys/devices/ocp.3/pwm_test_P8_13.15/"
static bool test_path(uint8_t *path);
static int8_t set_period(uint8_t *path, uint8_t *num);
static int8_t set_duty(uint8_t *path, uint8_t *num);
static int8_t set_polarity(uint8_t *path, uint8_t *num);
static int8_t set_run(uint8_t *path,int8_t *num);
int main (int argc, char **argv) {
uint8_t *prefix = DEFAULT_PREFIX;
if (test_path(prefix)) {
printf("Can\'t use that pathn");
return -1;
}
set_run(prefix,"0");
set_period(prefix, "1000000000");//20
set_duty(prefix, "50000000");//10
set_polarity(prefix, "1");
set_run(prefix,"1");
return 0;
}
static bool test_path(uint8_t *path) {
uint8_t file[128];
struct stat *tmp;
snprintf(file, 128, "%s%s", path, "duty");
return access(file, W_OK);
}
static int8_t set_period(uint8_t *path, uint8_t *num) {
int32_t fd;
int32_t ret;
uint8_t file[128];
snprintf(file, 128, "%s%s", path, "period");
fd = open(file, O_WRONLY);
if (-1 == fd)
printf("can\'t set periodn");
ret = write(fd, num, strlen(num));
if (-1 == ret)
printf("can\'t set period to %s %sn", file, num);
return close(fd);
}
static int8_t set_duty(uint8_t *path, uint8_t *num) {
int32_t fd;
int32_t ret;
uint8_t file[128];
snprintf(file, 128, "%s%s", path, "duty");
fd = open(file, O_WRONLY);
if (-1 == fd)
printf("can\'t set dutyn");
ret = write(fd, num, strlen(num));
if (-1 == ret)
printf("can\'t set duty to %sn", num);
return close(fd);
}
static int8_t set_polarity(uint8_t *path, uint8_t *num) {
int32_t fd;
int32_t ret;
uint8_t file[128];
snprintf(file, 128, "%s%s", path, "polarity");
fd = open(file, O_WRONLY);
if (-1 == fd)
printf("can\'t set polarityn");
ret = write(fd, num, strlen(num));
if (-1 == ret)
printf("can\'t set polarity to %sn", num);
return close(fd);
}
4 效果
关注微信公众号【口袋物联】,微信号为koudaiwulian,更多物联网知识等着你
BeagleBone Green开发板试用帖汇总
|