PWM 参数计算

pwm模块可以设置的参数有prescaler, period, duty.
period参数的大小决定了这个pwm的分辨率。比如period有12位,即它的一个周期最多可以分为4096个等级。
cpu提供clk给pwm模块, pwm需要对这个clk做分频动作,分频系数由prescaler决定。

linux 中pwm接口位于<linux/pwm.h>,其中有

int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);

其参数定义, period_ns为pwm最终输出脉冲的周期,duty_ns为pwm最终输出脉冲周期中占空比时间(高电平时间)。

在这个函数中要要据两个输出参数计算出pwm各参数的配置值。


计算步骤
1. 供给pwm的clk,频率为fclk, 周期 t0 = 1/fclk
2. clk经过perscaler的分频之后,每周期时间 t1 = t0 / (perscaler+1) = (perscaler+1) / fclk
3. pwm分辨率为4096, 最大限度使用这个分辨率,则4096中的每一级占一个分频后的clock,所以最终输出脉冲的周期为:
    period_ns = t1 * 4096 = (1/fclk) * (perscaler + 1) * 4096

而在pwm_config()函数中,给定period_ns和原始clk,在函数中计算出perscaler等参数。

	c = pwm_source_clk; //origin clk
	c = c * period_ns;
	do_div(c, 1000000000);
	period_cycles = c;

	if (period_cycles < 1)
		period_cycles = 1;
	prescale = (period_cycles - 1) / 4096;
	pv = period_cycles / (prescale + 1) - 1;
	if (pv > 4095)
		pv = 4095;

	if (prescale > 1023)
		return -EINVAL;

	c = (unsigned long long)pv * duty_ns;
	do_div(c, period_ns);
	dc = c;
最后得到 prescale, pv, dc 分别是设置入寄存器prescaler, period, duty域中。
posted @ 2013-04-25 19:22  sammei  阅读(7390)  评论(0编辑  收藏  举报