如何限制PWM占空比值的范围?

How to limit the range of PWM duty-cycle values?

我很难发现我怀疑我的代码中有一个非常愚蠢的错误。我正在使用 ATmega328。

我需要的是生成一个 PWM 信号,其占空比不在 0% 和 100% 之间变化,而是在其他两个值之间变化。通过设置宏 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的值增加时,在某个时候占空比停止增加returns到0,然后继续增加,直到达到0……整个ADC范围内的四次。

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

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

通过将

的结果截断为 16 位,我已经能够 几乎 复制您的症状
(duty*(duty_max-duty_min))/1023

当占空比为 347 时,输出值从 114(约为最大值的 47%)下降到 50,这是最小占空比。这种情况发生 3 次,在输入范围内(不是 4)有一点

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

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

看看这是否改变了什么。