www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Compare Match in Software (kein PWM)


Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich suche nach einem Tipp wie ich bei einem durchlaufenden 16-bit Timer 
eine "Compare Match" Einheit in Software nachbilden kann. Damit soll 
eine variable Frequenz generiert werden. Der Timer darf nicht verändert 
werden.

Wäre eine (Hardware-) Compare Match Einheit frei würde man immer im 
OC-Interrupt die nächste Periode auf den alten OCR-Wert aufaddieren und 
ins OCR schreiben.

In Software kann man nicht davon ausgehen genau zu "treffen" (Counter == 
Compare Value), sondern muss (Counter >= Compare Value) prüfen. Das 
funktioniert solange gut bis der Counter rumläuft und wieder bei 0 
startet. Um das zu merken muss ich den Overflow auswerten.

Pseudocode:
CNT = 13543
OC = 32000

if ((CNT >= OC) || (OVF))   // erste Bedingung wahr
{
[CNT == 34674]
OC = OC + 32000 = 64000
OVF = false
...
}

if ((CNT >= OC) || (OVF))   // zweite Bedingung wahr
{
[CNT == 367]
OC = OC + 32000 = 64000
OVF = false
...
}

Problemfall:
CNT = 61543
OC = OC + x = 32000

sofort:

if ((CNT >= OC) || (OVF))   // erste Bedingung wahr -> FALSCH

nach Überlauf:

if ((CNT >= OC) || (OVF))   // zweite Bedingung wahr -> FALSCH

Hat jemand eine Idee das ganze EFFIZIENT zu implementieren. Das ist doch 
bestimmt mit nem guten Trick einfach möglich...

Grüße
Robert

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde einfach vom Counter den Compare-Wert abziehen, und die 
Differenz dann auf kleiner einer Konstante testen. Der Vergleich liefert 
dir dann die Info, ob sich der Counter innerhalb des Fensters OC - 
OC+Konstante befindet. Und das ganz ohne sich Gedanken um Überläufe 
machen zu müssen.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

das kann imho nicht funktionieren da ich bei der Differenzbildung (was 
auch ein Vergleich ist) nicht unterscheiden kann zwischen "Counter ist 
zwar größer aber muss noch einmal rum" und "Counter ist größer und hat 
den OC-Wert passiert".

Grüße
Robert

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robert schrieb:
> das kann imho nicht funktionieren da ich bei der Differenzbildung (was
> auch ein Vergleich ist) nicht unterscheiden kann zwischen "Counter ist
> zwar größer aber muss noch einmal rum" und "Counter ist größer und hat
> den OC-Wert passiert".

Das kommt ganz darauf an, mit was für Perioden du überhaupt konkret 
arbeitest. Das funktioniert nur dann nicht, wenn nach dem Aufaddieren 
der neue Compare-Wert wieder im Bereich des alten Compare-Wertes liegt 
(bzw. genauer: wenn der neue Wert im Bereich Counter-Konstante - Counter 
liegt).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Robert schrieb:

> das kann imho nicht funktionieren da ich bei der Differenzbildung (was
> auch ein Vergleich ist) nicht unterscheiden kann zwischen "Counter ist
> zwar größer aber muss noch einmal rum" und "Counter ist größer und hat
> den OC-Wert passiert".

Es funktioniert schon, aber du darfst dir nicht den neuen OCR Wert nach 
dem Muster

   nächster_OCR = ZyklusStart + OCR_Delta

ausrechnen.
Statt dessen musst du vergleichen

   if( aktueller_Timer - ZyklusStart > OCR_Delta )
     // OCR wurde überschritten

aber wie bereits angesprochen: das funktioniert solange, solange du 
nicht einen kompletten Timer_einmal_rum verpasst.

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ihr beiden,

ihr habt völlig recht - es funktioniert sehr gut. Hätte nicht gedacht 
dass das so einfach lösbar ist.

Grüße
Robert

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.