Forum: Mikrocontroller und Digitale Elektronik Tiny2313: 4 Kanal PWM + IR Decoder; wie noch Zeit messen?


von Timmo H. (masterfx)


Lesenswert?

Hallo zusammen.
Ich stehe vor folgendem Problem.
Ich habe einen Attiny2313. Dieser hat ja 4 PWM Kanäle die auch alle 
gleichzeitig im 8-Bit Modus benutzt werden, da separat mehrere 
LED-Leuchtmittel gedimmt werden sollen.
Die Helligkeit dieser Kanäle soll über eine IR Fernbedienung eingestellt 
werden können. Soweit so gut.
Nun habe ich jedoch das Problem, dass ich für die Decodierung der 
IR-Signale die High- und Low-Zeiten messen muss. Nun habe ich gedacht, 
dass ich zusätzlich noch den Timer Overflow Interrupt verwenden könnte, 
jedoch kann ich nicht feststellen ob der Counter gerade rückwärts oder 
vorwärts läuft und ich damit nicht die richtige Zeitdifferenz errechnen 
kann.
Der PWM läuft als Phase Correct PWM, damit ich auch ein echtes 
"Nullsignal" erzeugen kann. Sprich der Counter geht von BOTTOM nach TOP 
und dann wieder nach BOTTOM.

Der IR-Empfänger (TSOP) hängt an INT1 und löst sowohl bei steigender als 
auch bei fallender Flanke einen Interrupt aus. In der ISR will ich nun 
die Zeiten der IR-Signale messen.

Wie kann ich jetzt bestimmen wie lange die Low- bzw. Highphase eines 
IR-Signals genauer hat.
Mit einem Konstrukt in der Main-Funktion wie
1
while(1){
2
3
   _delay_us(10);
4
   timer++;
5
}
und einer Auswertung in der INT1 ISR:
1
ISR(INT1_vect){
2
  if(first == 0){
3
    first = 1;
4
    timer= 0;
5
  }
6
  else{
7
    if(timer > 40 && timer < 60){
8
      code <<= 1;
9
    }
10
    else if(timer > 100 && timer < 150){
11
      code |= 1;
12
      code <<= 1;
13
    }
14
    count++;
15
    first = 0;    
16
  }
17
  if(count == 25){
18
    done = 1;
19
    count = 0;
20
  }
21
}
scheint es sehr ungenau zu sein, sodass ich die Zeitfenster recht 
großzügig auslegen muss, damit es auch nur ansatzweise funktioniert.

Hat jemand eine Idee wie ich das am geschicktesten realisieren kann?

von MaWin (Gast)


Lesenswert?

Du lässt den Hardwaretimer immer rumlaufen, für nichts bestimmtes, nie 
rücksetzen.

Um die Zeit zu messen, nimmst du am Anfang seinen Wert und ziehst ihn 
vom Wert am Ende ab. Das klappt sogar bei Überlauf des Timers.

So macht es de PC auch, ein Timer reicht für alle Aktionen.

Willst du längere Zeiten messen, addierst du die Überläufe so einer 
Subtraktion in einen Überlaufwert hinein.

von Timmo H. (masterfx)


Lesenswert?

Ja das ist schon klar, aber dann müsste ich komplett Software PWM 
betreiben. Nun laufen die Timer ja beide im 8 Bit Phase Correct PWM. 
Sprich der Counter läuft nicht "im Kreis" sondern er geht von 0x00 bis 
0xFF und läuft dann wieder rückwärts bis 0x00 und löst dann erst den 
Overflow Interrupt aus. Und da ich die aktuelle Zählrichtung nicht 
auslesen kann kann ich die Zeitdifferenz nicht bestimmen.
Ich habe ja nur diese zwei Counter/Timer und muss diese also zusätzlich 
zu PWM noch irgendwie als Zähler missbrauchen.

von MaWin (Gast)


Lesenswert?

Du dimmst LEDs, was willst du da mit Hardware-PWM ?


Das istvdoch wie 255er Goodyear auf der Seifenkiste...

von Falk B. (falk)


Lesenswert?

@  Timmo H. (masterfx)

>Ja das ist schon klar, aber dann müsste ich komplett Software PWM
>betreiben.

Kann man, mit Soft-PWM, muss man aber nicht.

> Nun laufen die Timer ja beide im 8 Bit Phase Correct PWM.

Vollkommen unsinnig. Mach Fast PWM und gut.

>Ich habe ja nur diese zwei Counter/Timer

Was mehr als ausreichend ist.

MfG
Falk

von Timmo H. (masterfx)


Lesenswert?

Falk Brunner schrieb:
> Vollkommen unsinnig. Mach Fast PWM und gut.
Das hatte ich probiert, aber irgendwie war bei Fast PWM bei OCR0A und 
OCR0B = 0 immernoch ein "Spike"

von Falk B. (falk)


Lesenswert?

@  Timmo H. (masterfx)

>> Vollkommen unsinnig. Mach Fast PWM und gut.
>Das hatte ich probiert, aber irgendwie war bei Fast PWM bei OCR0A und
>OCR0B = 0 immernoch ein "Spike"

Ja, das ist bekannt, steht auch so im Datenblatt. Das Problem ist aber 
leicht lösbar. Bei PWM==0 schaltet man den PWM-Ausgang als normalen 
Ausgang auf LOW ;-)

MFG
Falk

von spess53 (Gast)


Lesenswert?

Hi

>Ja, das ist bekannt, steht auch so im Datenblatt. Das Problem ist aber
>leicht lösbar. Bei PWM==0 schaltet man den PWM-Ausgang als normalen
>Ausgang auf LOW ;-)

Oder negierte PWM.

MfG Spess

von Timmo H. (masterfx)


Lesenswert?

mmh, also bei Fast PWM bekomme ich aber einen Interrupt bei MAX bzw. TOP 
und habe quasi keine Möglichkeit im richtigen Moment den Port auf 0 zu 
setzen...bzw. ich müsste die Ports wieder auf Normal Operation stellen 
und dann auf 0. Bissl umständlich irgendwie
Komischerweise verhalten sich Timer0 und Timer1 auch unterschiedlich.
Wenn ich beide in 8 Bit Fast PWM schalte, also
1
TCCR0A=(1<<WGM01)|(1<<WGM00)|(1<<COM0A1)|(1<<COM0B1);
2
TCCR0B=(1<<CS01)|(1<<CS00);
3
4
TCCR1A =(1<<WGM10)|(1<<COM1A1)|(1<<COM1B1);
5
TCCR1B=(1<<WGM12)<(1<<CS11)|(1<<CS10);
scheinen die OCR's vom Timer1 auf 0 zu gehen (LEDs ganz aus) die von 
Timer0 jedoch nicht.

von Simon K. (simon) Benutzerseite


Lesenswert?

Ich glaube das hast du falsch verstanden. Du sollst, falls der OCR Wert 
0 ist, einfach den Pin auf 0 stellen. Wenn der nicht 0 ist, einfach den 
Pin wieder auf die PWM setzen und den OCR Wert setzen.

von Timmo H. (masterfx)


Lesenswert?

Ok, das mit der unterschiedlichen Funktionsweise war mein Fehler 
(Syntax). Aber so wirklich gefallen tut mir das nicht mit dem Port auf 0 
setzen bzw. wieder auf PWM. Der Code wird durch die zusätzlichen 
if-Bedingungen mal eben um gut 100 Bytes aufgebläht. So langsam wirds 
eng mit der IR-Funktionalität...

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.