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