2017-10-05 28 views
0

私は、2つの異なるADCからの2つの測定値とそれらに関連する2つの異なるPWM信号が必要なプロジェクトを行っています。測定された値は、変数freqdutyに格納されます。名前が示すように、私はfreqの値に応じて1つのPWM信号の周波数を変化させ、もう一方はdutyに依存してそのデューティサイクルを変えなければなりません。問題は、最初の信号は正常に動作しますが、2番目の信号は正常ではありません。なぜPWM信号が出力されないのですか?

私はATmega328pを使用しています。私は変数dutyの代わりに一定の値を使用しようとしましたが、同じことが起こりました。 PWM信号の代わりに、出力ピン(OC0B)は常にハイ、すなわち5V DCに設定されています。私はTCCR0レジスタの値をトリプルチェックした

//Timer0 configuration 
TCCR0A = 0b00100011; 
TCCR0B = 0b00001001; //Fast PWM, no prescaler, non-inverted, out OC0B 
OCR0B = duty; 

が、すべてが正しいように思える:機能は本当に簡単です。この現象の原因は何ですか?

+0

[このWebページ](http://www.avrfreaks.net/forum/solved-atmega328p-output-pwm-oc0a-and-oc0b)上のそれについて広範な議論があります。 –

+0

モード7の代わりにモード3を使用したいと思うかもしれません。あるいは、 'OCR0A'を設定するのを忘れているかもしれません。 –

+0

@EdgarBonet私の知らないことは申し訳ありませんが、どういう意味ですか?私はあなたが「モード3」または「モード3」の意味を理解していません。また、B出力を使用したい場合、なぜ 'OCR0A'を設定するのですか? – Tendero

答えて

0

完全な回答に私のコメントを拡大してください。

page 140 of the datasheetには、すべて「波形生成モード」の を示す表があります。あなたの質問に表示されるコードは モードにタイマ  7を設定します:TOPの高速PWM   = OCR0A。この モードでは、タイマは0からOCR0Aに格納された値までカウントし、その後 がロールバックして再び開始します。このモードを使用して、 OC0BにPWM信号を生成することができます。その後、信号(OCR0Aレジスタを設定することにより)とパルス幅(OCR0Bを介して)の両方を制御することができます。 OCR0Aを設定しないと、デフォルトで0になり、動作しません。

クロックサイクルが256  で満足していて、 に変更したくない場合は、  255をOCR0Aに書き込むことができます。あるいは、 は、タイマ を3に設定することができます:TOP   = 0xffの高速PWM。 このモードでは、OCR0Aに格納されている値 にかかわらず、周期は256  サイクルです。以下

なお、パルス幅は64回のCPUサイクルであり、 期間256回の サイクルであるPWM信号を生成するモードの使用を示す簡単なテストプログラムです。

#include <avr/io.h> 

int main(void) 
{ 
    uint8_t duty = 64; 

    // Set pin PD5 = OC0B as output. 
    DDRD |= _BV(PD5); 

    // Configure Timer 0. 
    OCR0B = duty - 1; // set duty cycle 
    TCCR0A = _BV(COM0B1) // non-inverting PWM on OC0B 
      | _BV(WGM00) // mode 3: fast PWM, top = 0xff 
      | _BV(WGM01); // ditto 
    TCCR0B = _BV(CS00); // clock at F_CPU 

    for (;;) ; 
} 
関連する問題