Go Down

Topic: Timer 2 15 khz frequenz mit variabler duty cycle (Read 4951 times) previous topic - next topic

murdok1980

Ich bräuchte am Pin 11 eine Frequenz vom 15,6 khz mit variabler duty cycle. Das alles mit dem Timer 2 die 8bit reichen mir. Mit dem Timer 1 hab ich das schon für 2 Kanäle erreicht. Hab dafür ICR als Top Wert genommen und OCR1A und OCR1B als variable duty cycle.
Den Modus gibt es aber bei Timer 2 nicht und mit dem Togglen eines Pins kenn ich mich nicht so aus.
Ich brauch das für einen 3. PWM Kanal.
Kann mir jemand beim Bitsetzen in die Register helfen.
Nutze nen Arduino Nano.
Grüße
Andre

Doc_Arduino

#1
Feb 09, 2016, 04:18 pm Last Edit: Feb 09, 2016, 04:40 pm by Doc_Arduino
Hallo,

wenn du dein Wissen von Timer 1 auf Timer 2 überträgst, sollte das Ding laufen.
Blick ins Datenblatt ist nicht ausreichend? Ab Kapitel 20 im Datenblatt.

Wobei die Wunsch 15kHz wohl nicht möglich sind. Der Takt wird nur von den 16MHz µC und dem eingestellten Prescaler beeinflusst.

Ansonsten könnte man bestimmt noch "tricksen" indem man im Timer ISR  x beliebige Pins je nach Timer Counter schalten läßt. Sowas in der Art wurde hier mal besprochen. Bitte mal lesen. Aus der Kalten heraus mach ich das auch nicht.   http://forum.arduino.cc/index.php?topic=359685

Edit:
zeig mal bitte deinen bisherigen Code ( in </> Code Tags bitte oder .ino Datei ranhängen)
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

gregorss

Ich bräuchte am Pin 11 ...
Als ich einmal versucht habe, einen Code, der auf Pin 3 Timer-gesteuert arbeitete, auf einen anderen Pin „umzuziehen", hat sich herausgestellt, dass es nicht funktionieren kann, weil sich dann die Bedeutung eines Registers ändert. Was vorher als „Output Compare"-Wert interpretiert wurde, wurde zu irgendeinem „Top-" oder „Down-Wert".

Seither weiß ich, dass Timerprogrammierung nicht ganz einfach ist und längst nicht alles auf allen Pins machbar ist. Und obwohl ich den betreffenden Teil des (ATmega328-) Datenblattes mehrmals konzentiert durchgelesen hatte, habe ich das Problem nicht selbst gefunden.

Der Code, von dem ich damals ausgegangen bin, basierte auf der Application Note auf dieser Seite.

Grundsätzlich wäre gut, wenn Du Deinen (aufgeräumten ;-) Code mal zeigen könntest.

Gruß

Gregor
Mir wird übel. (Uwe)

Doc_Arduino

Hallo,

das mit dem Pin 11 und Timer 2 haut auf dem Uno schon hin. Ist der hardware kodierte Timer 2 Pin OC2A.
Sollte auch für den Nano gültig sein, denke ich.

Ich hätte jetzt ein Bsp. fertig mit Mode 3 für den Timer 2. Aber wenn der TO keinen Code zeigt, gibts nichts.

Mode 7 bekomme ich noch nicht hin. Macht aber denke ich, mit weniger als 8Bit Auflösung auch keinen Sinn.
Wobei ich zugeben muß, dass die Registerbezeichnung beim Timer 2 im Datenblatt schon etwas anders ist. Die Namen wie im Datenblatt kennt der Compiler einfach nicht. Zum Bsp. OCRA. OCR2A und OCR2B gibt es, steht aber so nicht im Datenblatt. Weis noch nicht so recht was den Datenblatt Schreiberling dabei geritten hat.


Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

Die einzige Stelle wo "OCRA" auftaucht ist in der Waveform Generation Tabelle. Überall anders steht die genaue Bezeichnung.

gregorss

#5
Feb 09, 2016, 06:36 pm Last Edit: Feb 09, 2016, 06:37 pm by gregorss
...
Wobei ich zugeben muß, dass die Registerbezeichnung beim Timer 2 im Datenblatt schon etwas anders ist. Die Namen wie im Datenblatt kennt der Compiler einfach nicht. Zum Bsp. OCRA. OCR2A und OCR2B gibt es, steht aber so nicht im Datenblatt. Weis noch nicht so recht was den Datenblatt Schreiberling dabei geritten hat.
Was meinst Du? In meiner Version des Datenblattes stehen einwandfreie Namen drin (http://test.szaktilla.de/shot.png). Ich habe da nur mal willkürlich ein paar Markierungen reingemalt.

Gruß

Gregor
Mir wird übel. (Uwe)

Doc_Arduino

#6
Feb 09, 2016, 06:56 pm Last Edit: Feb 09, 2016, 07:00 pm by Doc_Arduino
Hallo,

ich rede vom Datenblatt von meinem Mega2560 im Kapitel 20 - Timer 2. Dabei interessiert mich die außere Pinbelegung noch nicht wirklich. Aus dem Kapitel möchte ich nur herauslesen welches Register was macht und wie ich es setzen muß.

Also kann man sagen das in der Tabelle mit OCRA eigentlich OCR2A gemeint ist?
Irgendeine Timer Nummer muß ja enthalten sein im Namen.

Was ich auch probiert hatte war mit dem digitalWrite(Pin, LOW);
Klappte aber nicht. Einmal 0 immer 0.
Dann habe ich nachgeschaut wie das in der wiring_analog gemacht wird.
Klappte aber mit auch nicht. Einmal 0 immer 0.
Code: [Select]

int value = analogRead(_Poti)/4;  
  
  if (value == 0)  {
    digitalWrite(_PWMpin, LOW);   // PWM 0% an Pin 10
  }
  else  {
    TCCR2A = (1<<COM2A1);
    OCR2A = value;                // PWM x% an Pin 10
  }


Mich wundert auch das "Arduino" zum jedesmal neu setzen der Register die Interrupts nicht ausschaltet.

Edit:
ähm ja, ich muß ja entweder das Register komplett neu setzen wie beim Timer setzen oder nur das eine Bit zwischendurch. Mein Fehler. Scheinbar wird mit digitalWrite der gesamte Timer zurückgesetzt. Oder so ähnlich.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

Musst du do
Also kann man sagen das in der Tabelle mit OCRA eigentlich OCR2A gemeint ist?
Irgendeine Timer Nummer muß ja enthalten sein im Namen.
Ja. Ich das nie anders verstanden

Doc_Arduino

#8
Feb 09, 2016, 07:03 pm Last Edit: Feb 09, 2016, 07:04 pm by Doc_Arduino
Hallo,

bestimmt sollte da stehen OCRnA oder eben gleich OCR2A.
Ähnlich wie beim Timer 1. Da ist alles glas klar.  :)

Warum in der wiring_analog jedoch keine ISR's ausgeschalten werden müssen würde mich schon interessieren.  ;)
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

ähm ja, ich muß ja entweder das Register komplett neu setzen wie beim Timer setzen oder nur das eine Bit zwischendurch. Mein Fehler. Scheinbar wird mit digitalWrite der gesamte Timer zurückgesetzt. Oder so ähnlich.
Eigentlich sollte nur das entsprechende COMnA/B1 Bit gelöscht werden. Siehe turnOffPWM() in wiring_digital.c

z.B.:
Code: [Select]

#if defined(TCCR2A) && defined(COM2A1)
case  TIMER2A:  cbi(TCCR2A, COM2A1);    break;
#endif
#if defined(TCCR2A) && defined(COM2B1)
case  TIMER2B:  cbi(TCCR2A, COM2B1);    break;
#endif

Doc_Arduino

Hallo,

ja, macht es auch. Ich hatte aber dummerweise nur immer das eine Bit in das komplette Register geschrieben. Die anderen gesetzten Bits damit gelöscht.  :)

Wenn ich nun sbi definiere, dann klappt auch nur das Bit setzen.   :)

Code: [Select]

sbi(TCCR2A, COM2A1);


Nur warum müssen dafür die Interrupts nicht ausgeschaltet werden? Soll man doch machen denke ich.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

murdok1980

Den Teil für die PWM des Timers 1 setz ich dann gleich rein.

murdok1980

@ doc_arduino
Wie versprochen der Codeteil für die PWM an PIN 9 und 10.
Code: [Select]

TCCR1A = _BV(COM1A1) | _BV(COM1B1) ;      // Phase und Frequenz correct Modus. Nicht invertiert Modus
TCCR1B = _BV(WGM13) | _BV(CS10);           // Auswahl Modus 8 mit Teiler 1 zum CPU Takt
ICR1 = 512;// ICR1 = 512, Frequenz = 15,625kHz (16000000 Hz / ( 2 x Prescaler x 512 ))


und in die Register OCR1A und OCR1B schreib ich dann die entsprechende Werte die ich für die duty cycle brauch und steuer 2 H-Brücken Treiber an. Der Wert für die OCR1A und OCR1B Register kommt aus einem RC Empfänger, welchen ich am PIN 2 und 3 auslese.

Es soll ja nicht so aussehen als wöllte ich hier nur schnorren wollen.
So wie das Beispiel oben geht das beim Timer 2 ja nicht weil entsprechende Register fehlen aber eine etwa gleiche Funktion müsste gehen. Wie gesagt die 8Bit reichen mir aus.

Grüße Andre

Serenifly

Bei Timer2 geht das mit einem Pin. Aber nicht mit zwei. Der Vorteil von Timer1 ist eben das Input Capture Register. Das wird dann in dem Modus als TOP genommen, so dass man beide Output Compare Register frei hat.

Doc_Arduino

Hallo,

deinen Versuchscode vom Timer 2 zeigste uns nicht?   Bin heute aber streng.  :)
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Go Up