Hallo, ich versuche gerade, einen Infrarot-Fernbedienungs-Sender im Biphase/Manchester-Verfahren für den ATmega8 zu codieren. Leider ist beim Anschluss einer (normalen) LED nichts zu sehen – es scheint mir, dass die Interruptroutine ir_intr überhaupt nicht aufgerufen wird. Nachdem ich heute schon einige Stunden daran sitze und nach Fehlern suche, möchte ich meinen Code nun hier posten und um Hilfe bitten – vielleicht fällt jemandem etwas auf, was ich bisher übersehen habe. Ich hoffe, dass der recht einfache Code selbsterklärend und einigermaßen gut kommentiert ist. Gruß und einen schönen Sonntag.
Auf den ersten Blick scheint mir, Sie verwechselten (an drei Stellen) TCNT2 mit TCCR2. Aber so richtig kann ich das Oszilloskopbild noch nicht interpretieren, vielleicht kommen Sie nach der entsprechenden Korrektur weiter.
1 | ; in temp0, TCCR2 |
2 | ; sbrc temp0, CS20 |
3 | in temp0,TCNT2 |
4 | sbrc temp0, 0 |
S. L. schrieb: > Auf den ersten Blick scheint mir, Sie verwechselten (an drei Stellen) > TCNT2 mit TCCR2. Vielen Dank erstmal für Ihre Antwort. Also in den Zeilen 111, 130 und 136 ist TCCR2 korrekt – da geht es darum, in Abhängigkeit davon zu verzweigen, ob der Timer2 läuft (also CS20==1) oder stillsteht (CS20==0).
S. L. schrieb: > Aber so richtig kann ich das Oszilloskopbild noch nicht > interpretieren Welches Oszilloskop-Bild?
> ... ob der Timer2 läuft ... Okay, das habe ich falsch verstanden. > Leider ist beim Anschluss einer (normalen) LED nichts zu sehen Also ich sehe Impulsfolgen auf dem Oszilloskop, nach Betätigen von SWITCH0 und SWITCH1; und die sind (natürlich) auch mit der LED zu sehen.
Beitrag #7520659 wurde von einem Moderator gelöscht.
Der Timer läuft und die ISR wird aufgerufen. Vielleicht kommst du weiter, wenn du es Schritt für Schritt im Debugger ausführst.
S. L. schrieb: >> Leider ist beim Anschluss einer (normalen) LED nichts zu sehen > Also ich sehe Impulsfolgen auf dem Oszilloskop, nach Betätigen von > SWITCH0 und SWITCH1; und die sind (natürlich) auch mit der LED zu sehen. Okay, danke, da muss wohl mit meiner Hardware irgendwas nicht stimmen ... Stefan F. schrieb: > Der Timer läuft und die ISR wird aufgerufen. Vielleicht kommst du > weiter, wenn du es Schritt für Schritt im Debugger ausführst. Ah OK, dann werde ich den Debugger mal ausprobieren – danke für den Tipp.
> da muss wohl mit meiner Hardware irgendwas nicht stimmen
Korrekterweise sollte ich hinzufügen, dass ich mangels eines ATmega8 mit
dem (großen Bruder) ATmega16 arbeite; mutatis mutandis, d.h. OC1A liegt
bei mir auf D5 - darf aber keine Rolle spielen.
S. L. schrieb: > Korrekterweise sollte ich hinzufügen, dass ich mangels eines ATmega8 mit > dem (großen Bruder) ATmega16 arbeite Aber du benutzt die inc Datei vom ATmega 8. Das kann nicht funktionieren. Schon die Adressen der Interrupt Vektoren sind anders.
> ... kann nicht funktionieren ...
Was, bitte, soll da nicht funktionieren?:
1 | .org 0 |
2 | rjmp reset |
3 | .org OC2addr ; Timer2 Compare Match interrupt |
4 | rjmp ir_intr |
5 | .org INT_VECTORS_SIZE |
PS: Das .include habe ich natürlich auch angepasst.
:
Bearbeitet durch User
S. L. schrieb: > Was, bitte, soll da nicht funktionieren?: Ein Programm mit interrupt Vektoren vom Atmega8 kann auf dem Atmega16 nicht laufen, weil die Sprungadressen an der falschen Stelle im Speicher stehen.
Vorschlag: unterhalb von '; Even, just toggle the carrier:' die beiden rjmps vertauschen.
Stefan F. schrieb: > Ein Programm mit interrupt Vektoren vom Atmega8 kann auf dem Atmega16 > nicht laufen, weil die Sprungadressen an der falschen Stelle im Speicher > stehen. S. L. hat doch schon geschrieben, dass er/sie die Include-Datei angepasst hat, und es wurden die dort definierten Symbole für die Sprungadressen und Register etc. genutzt. Nichts für ungut, aber wo liegt also das Problem? S. L. schrieb: > Vorschlag: unterhalb von '; Even, just toggle the carrier:' die beiden > rjmps vertauschen. Hmm, das sollte eigentlich schon so stimmen, wie es da steht:
1 | sbrc temp0, CS20 |
springt zu
1 | rjmp ir_intr_carrierOn |
, falls CS20 null ist, also der Träger aus ist, welcher nachfolgend ab "ir_intr_carrierOn" eingeschaltet wird. Ist CS20 dagegen eins, der Träger also schon eingeschaltet, dann wird zu "ir_intr_carrierOff" gesprungen, also der Träger ausgeschaltet. Oder habe ich da irgendwo einen Denkfehler?
Ich habe jetzt den Code für den ATmega88A umgestrickt und auf einem anderen Board getestet und – tadaa, es funktioniert so, wie es soll. Den Interruptabstand habe ich in Zeile 68 durch einen Faktor 50 auf 500 ms vergrößert, damit man die Modulation an einer normalen LED beobachten kann. Scheinbar gab es wirklich irgendein Problem bei der Hardware mit dem ATmega8, oder es lag an der LED, die recht „dunkel“ ist, sodass das Blinken vielleicht nicht zu erkennen war ... Vielen Dank für die Antworten.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.