2023年12月20日水曜日

avr deep zone(2313)

AVRでのタイマとPWMの使い方 | うしこlog (nomaki.jp) も参考に

 #include <avr/io.h> // なくてもうごいたが

void setup(){

 TCCR1A=0b10100001; //   8ビット高速PWM動作

 TCCR1B=0b00001011;  //     clkI/O/64 (64分周)

// 7,11ピンの490Hzとそろえてみました。特に周期は問題になりませんが、モーターを滑らかに動かすには100Hz以上は必要らしいです(LEDは20~50Hz程度)。逆に周波数が高すぎるとノイズの発生、部品の劣化があるそうです。

OCR1A=0; // 初期化

OCR1B=0;

pinMode(12,OUTPUT); // 

pinMode(13,OUTPUT);

}

// analogWrite()を使うときは、pinMode()を設定する必要がないので省略していますが、レジスタを直接設定するときにはpinMode()が必要です。もしくは DDRB=0b00011000;

void loop() {

  analogWrite(11,127);   // timer0 A   

  analogWrite(7,0);   // timer0 B

 OCR1A=127;  // timer1 A デューティ比 50%(0~255)

 OCR1B=0;

  delay(500);

  analogWrite(11,0);   // timer0 A

  analogWrite(7,0);   // timer0 B

 OCR1A=0;

 OCR1B=0;

  delay(500);

  analogWrite(11,0);   // timer0 A

  analogWrite(7,127);   // timer0 B

 OCR1A=0;

 OCR1B=127;

  delay(500);

  analogWrite(11,0);   // timer0 A

  analogWrite(7,0);   // timer0 B

 OCR1A=0;

 OCR1B=0;

  delay(500);

}

// タイマ0、タイマ1のPWM4つをArduino(analogWrite()を使う)で設定しようとすると、なぜかATtiny2313ではタイマ1のPWMが反応しません。なのでタイマ0のPWMはArduinoのanalogWrite関数を使い、タイマ1のPWMはレジスタを直接設定しています。もちろんすべてレジスタを直接設定してもOKです。
// PWM周波数はATtinyCoreで、タイマは8MHz時488Hzに設定されているので、タイマ1も高速 PWM モードでそれに合わせました。なお位相基準PWMモードを使うと周波数が半分になりますが、のこぎり波を使う高速 PWM モードに比べて三角波を使うためPWM波形の位相がずれにくく、モーター制御には有利らしいです。
もう一点、タイマ1が使えなかったのはtone()が使っているからだそうです。よろしくお願いします。

以下ATtinyCoreより抜粋。
PWM周波数 
F_CPU:8MHz  F_PWM TC0:8/64/256= 488Hz  F_PWM TC1:8/64/256= 488Hz
TC0 は常に高速 PWM モードで実行されます。 ミリ秒には TC0 を使用しますが、位相補正モードはミリ秒タイマーでは使用できません。以下略。
トーンサポート
Tone() は Timer1 を使用します。最良の結果を得るには、ピン PB3 (12) または PB4 (13) を使用します。これは、割り込みを使用する代わりにハードウェア出力比較を使用して方形波を生成するためです。Tone() を使用するには、[第 2 タイマーの初期化: はい] を選択する必要があります。tone() は PB3 と PB4 の PWM を無効にします。
> 以前いただいた上記コードはたしかに動くのですが、attiny2313の添付ファイルにはOCR1Aという項目がなくOCR1AH,OCR1ALはありました ただ添付ファイルでもTCCR1Aはtimer0 8bitと明記されています このあたりの詳細おしえてください

このコードは確かArduinoで書くとタイマ1が動かないというので書いた覚えがあります。原因は「16ビットタイマがtoneライブラリ用に初期化されているためPWM出力ができない」と記憶しております。
そこでタイマ0はArduino、タイマ1はレジスタを直接制御し一番簡単な高速PWM8ビットを使いました。これだとTOP値が255なのでOCR1Aの0から7ビットまで指定すれば良いということになります。(OCR1Aの8から15ビットがOCR1AH)
つまりデューティー比50%ならOCR1A=127; またはOCR1A=0b01111111;(OCR1AL=0b01111111; OCR1AH=0b00000000; と同じ)となります。もっと細かく制御したければ9または10ビットを使うことになります。その時はLとHを指定する必要があります。
「TCCR1Aはtimer0 8bit」はタイマ1高速PWM8ビットの事かと思います。
うまく説明できたかどうか、よろしくお願いします。

0 件のコメント:

コメントを投稿