mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Tiny2313 Frequenz ändern ohne Timer anzuhalten


Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Ich möchte mit meinem Tiny2313 ein Rechteck an OC1A ausgeben mit dem CTC 
Mode. Also kein PWM, kontinuierliches Rechteck.

Jetzt möchte ich im gleichmäßigem Abstand zwischen 3 Frequenzen 
umschalten:
Beispiel:

...10kHz -- 100ms -- 23kHz -- 100ms -- 35kHz -- 100ms -- 10kHz...

Die Einzelfrequenzen einzustellen ist kein Problem. Kann ich messen. 
Werden auch ausgegeben.
Auch das Umschalten funktioniert soweit, dann kann ich die 
Einzelfreuqenzen zwar nicht mehr messen, aber ich sehe mit einem Oszi, 
wie das Rechteck hin und her wackelt.

Jetzt habe ich das Problem, das der Timer anscheinend machmal stehen 
bleibt und das Rechteck wird kurz abgeschaltet. Das passiert auch recht 
zufällig, also kein Muster zu erkennen.

Wenn ich die Frequenz umstelle und das Register OCR1AH/OCR1AL mit dem 
entsprechenden Wert beschreibe, muss ich dann noch abwarten bis das 
Compare Flag gesetzt wird?
Oder muss ich auf ein anderes Flag warten bevor die Frequenz 
umgeschaltet werden kann.

Danke euch.

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem beim "fliegenden Wechsel" ist, daß beim Umschalten auf eine 
höhere Frequenz der Wert im Counter größer sein kann, als der neu 
eingestellte im OCR. Dann läuft der Timer einmal die große Runde.

Der aktuelle Wert im Timer Counter muß immer kleiner sein als der neue 
Wert im Register. Das lässt sich aber problemlos abfragen.

mfg.

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

warten brauchst du auf nichts, allerdings solltest du die Register 
(..H/..L) in der richtigen Reihenfolge beschreiben (wenn du in ASM 
programmierst). Im CTC-Mode kann beim umschalten natürlich ein Jitter 
entstehen.

> Jetzt habe ich das Problem, das der Timer anscheinend machmal stehen
> bleibt und das Rechteck wird kurz abgeschaltet.
wie lang ist kurz?

Sascha

Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> wie lang ist kurz?

Ca. 500ms.

Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Eckmann:
> Der aktuelle Wert im Timer Counter muß immer kleiner sein als der neue
> Wert im Register. Das lässt sich aber problemlos abfragen.

Das werde ich mal noch einbauen.

Beim Beschreiben von H und L Register habe ich schon die Reihenfolge 
variiert. Aber ohne Erfolg. Liegt wohl daran, dass ich in C programmiert 
habe.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Dann schreib die neuen Werte im OC-Interrupt.

MfG Spess

Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb :
> Dann schreib die neuen Werte im OC-Interrupt.

Sorry, kannst du kurz erläutern was du damit meinst?

Danke

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Sorry, kannst du kurz erläutern was du damit meinst?

Du aktivierst den OC1A-Interrupt. Wenn der neue Wert geladen werden soll 
setzt du ein Flag (Variable). In der Interruptroutine machst du 
sinngemäß folgendes:

  if flag (
    OCR1A = newOC
    flag löschen )

MfG Spess

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan_KM schrieb:
> Liegt wohl daran, dass ich in C programmiert

Das liegt nicht an C, sondern daran, daß es egal ist.

mfg.

Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Ich habe den Timer 1 Interrupt aktiviert und folgende Routine 
geschrieben:

-----------------------------------------------------
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
 if (freq_flag)
  {
    OCR1AH=Tab_freqvalues[counter_freq]/256;   //Tabelle mit 
Frequenzwerten
    OCR1AL=Tab_freqvalues[counter_freq]%256;
    freq_flag=0;
    LED4=0;                     //schaltet eine LED ein, zur Kontrolle
  }
 else;

}

-----------------------------------------------------

an anderer Stelle im Programm passiert folgendes:
-----------------------------------------------------

......
counter_freq++;
if (counter_freq > 3) counter_freq=1;    // Obergrenze kontrollieren 
freq_flag=1;                             // nächste Freq. durch Timer1 
Int
while(freq_flag);               // warten bis Interrupt ausgelöst wird
......
-----------------------------------------------------

Freq_flag ist ein globale Variable. Mein counter_freq bestimmt den Wert 
aus einer Tabelle für die entsprechend neue Frequenz.
Es scheint so zu sein, dass das freq_flag nicht auf 1 gesetzt wird, 
sodass die entsprechende Routine in der Interrupt Routine nicht 
durchgeführt wird. Ich verstehe jedoch nicht wieso nicht.

Intterupt Initialisierung:

TIMSK=0x82;         // Aktivierung Interrupt für Timer 0 und Timer 1.

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void set_pwm( uint16_t val )
{
  if( val < OCR1A ){
    TIFR = 1<<OCF1A;
    while( !(TIFR & 1<<OCF1A));
  }
  OCR1A = val;
}


Peter

Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Peter.

Kannst du das kurz erläutern?

Danke

Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:

Wie muss ich meinen Timer 1 konfiguriert haben? Im PWM Mode, oder geht 
auch im CTC Mode.

Im Moment habe ich den Timer 1 im CTC Mode eingestellt mit aktiviertem 
Compare Match Interrupt.
Und da funktioniert nicht so wie ich es mir vorstelle.

Autor: Stefan_KM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es funktioniert jetzt. Danke Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.