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


von Robert (Gast)


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:
1
CNT = 13543
2
OC = 32000
3
4
if ((CNT >= OC) || (OVF))   // erste Bedingung wahr
5
{
6
[CNT == 34674]
7
OC = OC + 32000 = 64000
8
OVF = false
9
...
10
}
11
12
if ((CNT >= OC) || (OVF))   // zweite Bedingung wahr
13
{
14
[CNT == 367]
15
OC = OC + 32000 = 64000
16
OVF = false
17
...
18
}

Problemfall:
1
CNT = 61543
2
OC = OC + x = 32000
3
4
sofort:
5
6
if ((CNT >= OC) || (OVF))   // erste Bedingung wahr -> FALSCH
7
8
nach Überlauf:
9
10
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

von Stefan E. (sternst)


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.

von Robert (Gast)


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

von Stefan E. (sternst)


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).

von Karl H. (kbuchegg)


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.

von Robert (Gast)


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

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.