2017-10-14 32 views
0

私は、私のコードでかなりばかげて間違っていると思われるものを見つけるのに苦労しています。私はATmega328を使用しています。PWMデューティサイクル値の範囲を制限する方法は?

私が必要とするのは、デューティサイクルが0%と100%の間ではなく、2つの他の値の間で変化する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; 

私がいる問題は、その信号であり、それはすべきではありません。 ADCの読み取り値を0から1023まで掃引し、オシロスコープで出力信号を測定する場合、信号は最小デューティ・サイクルから安定して最大値まで上昇します。しかし、0〜40%(およそ)の4倍になります。つまり、ADCの値が増加すると、デューティ・サイクルは増加しなくなり、0に戻り、0になるまでデューティ・サイクルは増加し続けます。ADC範囲全体で4倍になります。

マッピング式をduty = round(duty/4);に置き換えても問題ありませんが、デューティサイクルは許容範囲外です(0%から100%になります)。

どうしてですか?間違いは写像式に入っていなければなりませんが、私はそれを見つけることができず、私はすでにそれをしばらく取り扱っています。

+0

どのタイプが 'duty'ですか? – flaviodesousa

+0

@flaviodesousa 'unsigned int'です。 – Tendero

+0

「広範な議論」のコメントは、それまでの質問と同じくらい関連性があります。実際にあなたを助けてくれない質問に対しては、何の答えも受け入れないでください。より多くの意見を得るには、質問に奨励金を使います。 –

答えて

0

Iはほとんどデューティが347である場合、出力値(最大値の約47%である)114から落下16ビットに

(duty*(duty_max-duty_min))/1023 

の結果を切り捨てることによってあなたの症状を複製することができました最小デューティ・サイクルである50に設定します。これは、が3回発生し、入力範囲(4ではなく)のビットがになります。あなたがしようとすると、この例では、公約数で両方の数値を分けるかもしれないこれを防ぐために

:デューティ差を、189は、3で割り切れる、そしてので1023は

duty = round((duty*63)/341) + duty_min; 
としてそれを書いてみです

この変更があるかどうかを確認してください。

関連する問題