5

Arduino Mega ( ATmega2560 ) でPWMを有効にしようとしていますが、いくつかの問題に直面しています。

まず、これをAdaでプログラムしようとしています。3 つの Timer3 チャネルを FastPWM で使用したいので、次のように書きました。

procedure Main is
begin

   -- Nullify Timer3 buffers
   TCCR3A := 0;
   TCCR3B := 0;
   TCCR3C := 0;

   -- Waveform Generation Mode
   --  Fast PW, 8-bit, TOP = 0x00FF, Update OCR3x at BOTTOM, TOV3 Flag Set on TOP
   --  => WGM33|WGM32|WGM31|WGM30 = 0|1|0|1
   TCCR3A := TCCR3A or TCCR3A_WGM30;
   TCCR3B := TCCR3B or TCCR3B_WGM32;

   -- Compare Output Mode:
   --  Fast PWM, non-inverting mode
   --  => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0
   TCCR3A := TCCR3A or TCCR3A_COM3A1 or TCCR3A_COM3B1 or TCCR3A_COM3C1;

   -- Clock Select: clk/1024 => CS32|CS31|CS30 = 1|1|1
   TCCR3B := TCCR3B or TCCR3B_CS32 or TCCR3B_CS31 or TCCR3B_CS30;

   -- Set Timer3 pins as output :
   -- Channel A : Digital Pin 5 / Chip Pin 5 (PE3/OC3A/AIN1)
   -- Channel B : Digital Pin 2 / Chip Pin 6 (PE4/OC3B/INT4)
   -- Channel C : Digital Pin 3 / Chip Pin 7 (PE5/OC3C/INT5)
   DDRE := DDRE_DDE3 or DDRE_DDE4 or DDRE_DDE5;

   OCR3AH := 0;
   OCR3AL := 250;

   OCR3BH := 0;
   OCR3BL := 250;

   OCR3CH := 0;
   OCR3CL := 250;

end Main;

ハードウェアの接続は問題ありません。Arduino IDE で簡単なコードを使用してテストしました。したがって、コードに何かが欠けているか、何かが間違っていることは明らかであり、これは PWM 初期化の問題が原因であるはずです。誰かが私がどこでそのような間違いをしたのか説明してもらえますか?

前もって感謝します。

アップデート

Ada でロジック全体を取得するのが難しい場合、C の同等のコードは次のとおりです ( AS6を使用してビルドできます。結果は同じです。つまり、信号は生成されません)。

int main(void){
    TCCR3A = 0;
    TCCR3B = 0;
    TCCR3C = 0;

    /* Waveform Generation Mode
    Fast PW, 8-bit, TOP = 0x00FF, Update OCR3x at BOTTOM, TOV3 Flag Set on TOP
    => WGM33|WGM32|WGM31|WGM30 = 0|1|0|1 */
    TCCR3A = TCCR3A|(1<<WGM30);
    TCCR3B = TCCR3B|(1<<WGM32);

    /* Compare Output Mode:
    Fast PWM, non-inverting mode
    => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0*/
    TCCR3A = TCCR3A|(1<<COM3A1)|(1<<COM3B1)|(1<<COM3C1);

    /* Clock Select: clk/1024 => CS32|CS31|CS30 = 1|1|1 */
    TCCR3B = TCCR3B|(1<<CS32)|(1<<CS31)|(1<<CS30);

    /* Set Timer3 pins as output :
    Channel A : Digital Pin 5 / Chip Pin 5 (PE3/OC3A/AIN1)
    Channel B : Digital Pin 2 / Chip Pin 6 (PE4/OC3B/INT4)
    Channel C : Digital Pin 3 / Chip Pin 7 (PE5/OC3C/INT5)*/
    DDRE = DDRE|(1<<DDE3)|(1<<DDE4)|(1<<DDE5);

    /* Set PWM Duty Cycles */
    OCR3AH = 0;
    OCR3AL = 250;

    OCR3BH = 0;
    OCR3BL = 250;

    OCR3CH = 0;
    OCR3CL = 250;
}
4

4 に答える 4

1

www.atmel.com/Images/doc2549.pdfの 136 ページを見ると、次の注記があります

「タイマー/カウンター 3 モジュールを有効にするには、57 ページの「PRR1 – 電力削減レジスタ 1」の電力削減タイマー/カウンター 3 ビット PRTIM3 に 0 を書き込む必要があります。

関連する可能性がありますか?

電源管理レジスタのデフォルトが何なのかわかりませんし、2560 も使用したことがありません。

自分で作成する代わりに、328p でタイマー ライブラリ avr-timer0.adb などを使用しましたが、残りは問題ないように見えます。

于 2012-11-19T16:41:33.973 に答える
1

一度に 1 つの観測結果が表示されます。これは正しくないことはほぼ確実です。

--  => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0
TCCR3A := TCCR3A or TCCR3A_COM3A1 or TCCR3A_COM3B1 or TCCR3A_COM3C1;

なんで?のような名前付き定数COM3A0は、ビット位置 (0 から 7) を示す整数のエイリアスにすぎないためです。C では、これらを設定すると、次のようになります。

REGISTER |= (1<<COM3A0);

と COM3A0 = 3 の場合、(1<<3)、または OR を取った 8 になります。

これは、1 を現在のレジスタ値と OR する前に左に桁数だけシフトします。 したがって、たとえば COM3A0 が既にビット シフトされていない限り、このステートメントは、いくつかの 1 と 0 の OR 演算を行い、単一の結果を TCCR3A に割り当てるだけです。

于 2017-08-03T11:09:14.300 に答える