【问题标题】:How to limit the range of PWM duty-cycle values?如何限制 PWM 占空比值的范围?
【发布时间】:2018-03-26 18:25:24
【问题描述】:

我很难在我的代码中找到我怀疑是一个非常愚蠢的错误。我正在使用 ATmega328。

我需要生成一个占空比不在 0% 和 100% 之间,而是在其他两个值之间变化的 PWM 信号。这通过设置宏duty_maxduty_min 来考虑。我在代码中所做的是读取分辨率为 1024 值的 ADC,并将读取的值映射到可接受值的范围:

#define duty_max 239
#define duty_min 50

[...]

//Reading the ADC
ADMUX = 0b01000101;
ADCSRA |= (1<<ADSC);
while(!(ADCSRA & (1<<ADIF)));
ADCSRA |= (1<<ADIF);
//Setting the variable 'duty' to the value read by the ADC
cli();
duty = ADC;
sei();
//Mapping to the range of accepted values
duty = round((duty*(duty_max-duty_min))/1023 + duty_min);

//Generating the PWM signal
OCR0B = duty;
//Timer 0
TCCR0A = 0b00100011;
TCCR0B = 0b00000001;

我遇到的问题是信号无法正常工作。当从 0 到 1023 扫描 ADC 读数并用示波器测量输出信号时,我希望信号从稳定的最小占空比变为最大值。但是,它从 0 到 40%(大约)四次。即当ADC值增加时,在某个时刻占空比停止增加并返回0,然后继续增加,直到达到0......整个ADC范围内的四倍。

如果我用duty = round(duty/4); 替换映射公式,它可以正常工作,但占空比超出了可接受的范围(从 0% 到 100%)。

为什么会这样?错误一定是在映射公式中,但我找不到,我已经处理了一段时间了。

【问题讨论】:

  • duty是哪种类型?
  • @flaviodesousa 是unsigned int
  • “广泛讨论”评论仍然与您之前的问题一样相关。请不要接受任何对您没有实际帮助的问题的答案。在问题上使用赏金以获得更多视图。

标签: c avr atmega pwm


【解决方案1】:

我已经能够几乎通过将

的结果截断为 16 位来复制您的症状
(duty*(duty_max-duty_min))/1023

当占空比为 347 时,输出值从 114(约为最大值的 47%)下降到 50,即最小占空比。这会在输入范围(不是四次)发生三倍多一点

为了防止这种情况发生,您可以尝试,在这种情况下,将两个数字除以一个公约数:占空比 189 可以被 3 整除,1023 也是如此。尝试将其写为

 duty = round((duty*63)/341) + duty_min;

看看这是否改变了什么。

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    相关资源
    最近更新 更多