Forum: Mikrocontroller und Digitale Elektronik Atmega8 Timerinterrupt Geschwindigkeit zur Laufzeit ändern


von JumboJ (Gast)


Lesenswert?

Hallo Lieben User,

ich habe mal eine Frage zum ATmega8 Timer. Ich möchte die 
Geschwindigkeit des Timerinterrupts über die Uart ändern. Klingt 
zunächst einfach, jedoch komme ich an dem Punkt der Berechnung der Zeit 
bzw der Frequenz nicht weiter und welchen Modus ich da am besten nutze.
Ich möchte beispielsweise über die Uart eine 5 für 5kHz senden und 
anschliessend soll mir ein Rechtecksignal mit der Frequenz generiert 
werden. Aber im Moment fehlt mir einfach der Groschen für die 
Verknüpfung von Quarz und Timer.
Wie ist das bei PWM? Ist da die Frequenz immer konstant und das 
Tastverhältnis kann nur geändert werden? Oder kann ich mit dem Mega8 
eine PWM mit DutyC. 50% erzeugen aber die Länge der High und Lowpegel 
ändern?
Für jeden Tip bedanke ich mich recht herzlich.
Schönen Abend
Jürgen

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin,

nimm den Timer-Overflow-Interrupt und verändere den Preloadwert 
dynamisch, wie du es möchtest...

Uwe

von JumboJ (Gast)


Lesenswert?

Vielen Dank Uwe...
kannst du mir das vielleicht ein wenig näher erläutern ? Bin im Bereich 
Timer nicht sehr weit und arbeite gerade nach und nach das Tutorial und 
das Datenblatt durch. Vielleicht kannst du mir das in 2 Takten :-) 
erklären?
Danke und Gruss
Jürgen

von Falk B. (falk)


Lesenswert?

@ JumboJ (Gast)

>kannst du mir das vielleicht ein wenig näher erläutern ? Bin im Bereich
>Timer nicht sehr weit und arbeite gerade nach und nach das Tutorial und
>das Datenblatt durch.

Dann tu das erstmal. Stichwort CTC-Modus.

MFg
Falk

von crazy horse (Gast)


Lesenswert?

Genau, CTC-Modus ist besser. Spart den Software-Reload (der sich schon 
mal was verzögern kann, wenn sich das Programm gerade in einem anderen 
Interrupt befindet oder Interrupts generell gerade gesperrt sind.
CTC läuft exakt.

von hans (Gast)


Lesenswert?

Bei 5 KHz für den CTC-Mode den Wert für das doppelte (hier 10 KHZ)
berechnen und den Ausgang auf Toggel stellen. Dann hat man
automatisch ein Rechteck mit der gewünschten Frequenz (bzw. der
machbaren Näherung) mit 50 % Duty.

gruß hans

von Flori (Gast)


Lesenswert?

ISR (TIMER2_COMP_vect)
{
PORTD^=(1<<PD7);
}

int main (void) {

  //Atmega8
  TCCR2 |= (1<<WGM21) | (1<<COM21) | (1<<CS20);
  TIMSK |= (1<< OCIE2);

  DDRB = 0xFF;
  DDRD = 0xFF;
  PORTD = 0x00;
  sei();

  while (1)
  {

  }
  cli();
  return 0;
}


Wie schnell sollte jetzt mein Signal sein? ich bekomm irgendwas mit 
7,8kHz, ist das korrekt?
Danke und LG

von Michael U. (amiga)


Lesenswert?

Hallo,

keine Ahnung, hab jetzt nicht alles abgesucht, ob Du irgendwo 
geschrieben hast, wie schnell Dein AVR getaktet ist...

Trotzdem ein paar Fragen zum Nachdenken:
wenn Du ein Rechtecksignal mit einer Frequenz erzeugen willst und dazu 
den Timer 2 im CTC-Mode laufen lässt mit WGM21 = 1
warum setzt Du dann COM21 = 1 (Clear OC2 on Compare Match) und nicht 
gleich COM20 = 1 (Toggle OC2 on Compare Match)?
Dann würde Dein Signal fix und fertig an OC2 ausgegeben werden, dann 
wäre keinerlei Eingriff nötig, auch kein Interrupt.

Weiter: wenn schon Interrupt, Du benutzt OCIE2, also Interrupt bei 
Compare Match. Auf welchem Wert steht denn bei Dir das Compare-Register 
(OCR2)?

Das bestimmt ja im CTC-Mode, wann der Interrupt ausgelöst wird, nämlich 
dann, wenn der Zähler den Wert von OCR2 erreicht...

Gruß aus Berlin
Michael

von Flori (Gast)


Lesenswert?

Vielen Dank Michael, warst mir eine Große Hilfe, auch wenns nicht mein 
Beitrag war :-)
Aber eine Frage hätte ich noch an der Stelle, Prozessor ist mit 3686400 
definiert, dann sollten 7200Hz am OC2 korrekt sein, wenn OCR2 auf 255 
gesetzt ist??? Oder wie berechne ich das bei CTC?
Besten Dank
Flo

von Michael U. (amiga)


Lesenswert?

Hallo,

3686400/256 = 14400 / 2 = 7200...

Ich müßte jetzt selbst das genaue Verhalten nachschlagen, meiner Meinung 
nach wir im Takt den Erreichen des Compare geschaltet, das wäre dann bei 
Vorteiler 1 mit 255+1=256 richtig.
Steht aber irgendwo im Datenblatt asl Diagramm oder so...

Gruß aus Berlin
Michael

von Flori (Gast)


Lesenswert?

es läuft so auch alles, aber irgendwie komme ich gerade mit dem debugger 
nicht ganz klar, wenn ich das unten stehende Programm simuliere, dann 
zählt TCNT2 irgendwie nur bis 0x0F bzw springt einfach nur von 0x07 auf 
0x0F ????
und jedesmal wenn die 0x0F gelöscht wird also nur noch 0x07 gesetzt ist, 
dann springt OC2 um. Ich verstehe nicht warum TCNT2 nicht bis OCR2 
zählt. Anscheinend ja schon im Taget, aber warum sehe ich das im AVR 
studio nicht?

#define  F_CPU 3686400
#define  M_CPU Atmega8
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

ISR (TIMER2_COMP_vect)
{
}

int main (void) {

  //Atmega8 3686400
  TCCR2 |= (1<<WGM21) | (1<<COM20) | (1<<CS20);
  TIMSK |= (1<< OCIE2);
  DDRB = 0xFF;
  OCR2=255;
  sei(); //Interrupts ON
     while (1)
      {

      }
  cli();
  return 0;
}


Danke und gruss

von Flori (Gast)


Lesenswert?

Keiner eine Idee warum der Debugger beim AVR-Studio zickt und auf dem 
Mega alles funktioniert?
gruss Flo

von STK500-Besitzer (Gast)


Lesenswert?

>Keiner eine Idee warum der Debugger beim AVR-Studio zickt und auf dem
>Mega alles funktioniert?

Der Simulator ist nicht perfekt. Atmel veröffentlicht aber irgendwo 
(vermutlich im AVRStudio) die Fehler des Simulators.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.