2017-10-14 97 views
0

我很难找到我怀疑在我的代码中是一个非常愚蠢的错误。我正在使用ATmega328。如何限制PWM占空比值的范围?

我需要的是产生一个PWM信号,其占空比不是介于0%和100%之间,而是介于另外两个值之间。这是通过设置宏duty_maxduty_min来考虑的。我在做什么在我的代码正在读取ADC技术,具有1024个值的分辨率,并映射读取接受值的范围值:

#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,然后持续增加,直到在整个ADC范围内达到0 ...四次。

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

这是怎么发生的?这个错误必须在映射公式中,但我找不到它,而且我现在已经处理了一段时间。

+0

哪种类型是“责任”? – flaviodesousa

+0

@flaviodesousa它是'unsigned int'。 – Tendero

+0

“广泛讨论”的评论仍然与您之前的问题相关。请不要接受任何实际上无法帮助您的问题的答案。在问题上使用赏金以获得更多观点。 –

回答

0

我已经能够几乎通过截断为16位的

(duty*(duty_max-duty_min))/1023 

结果当占空比是347时,输出值从114下降(其为约47%最大的)复制你的症状到50,这是最小的工作周期。在输入范围(而不是四个)上发生这三次

为了防止这种情况发生,你可以尝试,在这种情况下,通过一个共同的因子去除两个数字:持续时间差,189,是被3整除,所以是1023试着写它作为

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

看看这是否会改变任何东西。