Hi Leute, ich habe ein kleines Problem mit den externen Interrupts. Hardware: uC: ATmega8@1MHz Quellcode: im Anhang Es geht dabei um folgendes: An den Eingängen INT0 und INT1 des Atmegas liegt momentan dasselbe Signal. Dabei handelt es sich um ein Rechtecksignal mit einer Periodenlänge von ca. 4s mit einem Verhältnis von 50/50. Der Atmega soll nun, sobald das Signal anliegt, zunächst auf eine steigende Flanke reagieren. Sobald ein Interrupt ausgelöst wird, startet Timer0 (ext. Interrupt0=INT0) und Timer2 (ext. Interrupt1=INT1). Beide Timer laufen mit einer Frequenz von ca. 977Hz (1MHz/1024). Ebenfalls wird in der ISR die Reaktion auf steigende und fallende Flanke der ext. Interrupts umgestellt. Beide Timer lösen bei einem Overflow ebenfalls eine ISR aus. In ihr sollten die Ports PC0 und PC2, bedingt durch ihren derzeitigen Zustand, ein- bzw. ausgeschaltet werden. Jetzt zu meinem Problem: Eigentlich sollten die beiden Ports PC0 und PC2 nach meinem Verständnis beide zur etwa gleichen Zeit ein und ausgeschaltet werden. Sprich also: Bei der ersten steigenden Flanke sollten PC0 und PC2 nach 256/977Hz=0,26s eingeschaltet werden und nach der fallenden Flanke um ca. 0,26s verspätet ausgeschaltet werden. Und das ganze halt fortlaufend. Leider passiert genau das nicht. Sie schalten nämlich beide im Wechsel. Sprich, bei der ersten steigenden Flanke schaltet PC0 verspätet ein und schaltet auch erst wieder nach der nächsten steigenden Flanke+0,26s aus. In diesem Moment schaltet dann PC2 ein und das ganze dann im Wechsel. Kann mir da jemand weiter helfen, warum das so ist bzw. wie ich dieses Problem behebe? (Hoffe, ich konnte mich deutlich ausdrücken bzw. das Programm erklärt fragen) Danke
ok, wie ich gerade selber feststellen musste, klappt irgendwie das umschalten im Register MCUCR in der ISR nicht. Sprich also, die erkennung von "nur steigende flanke" auf "steigende und fallende flanke" in der ISR geht so nicht. Stellt sich nur die frage, warum nich? jemand eine idee?
ja - weil dum mit
>MCUCR = ((0<<ISC01) | (1<<ISC00))
die die anderen Bits löschst, und damit auf LOW-LEVEL Trigger
umschaltest!
Sascha
Magic Magicjon schrieb: > Stellt sich nur die frage, warum nich? jemand eine idee? nö, glaube ich auch nicht weil es dem atmel ziemlich egal ist ob er in einer ISR ist oder nicht, Man kann es nicht mal sicher rausfinden ob man in einer ISR ist oder nicht. Es wird also vermutlich nicht daran liegen.
Beim Umschalten kann evtl ein IRQ-Flag gesett werden, so daß direkt nach der ISR eine "Schein-IRQ" getriggert wird. Also entsprechende Flags nach Umsetzen von MCUCR löschen. Bits in MCUCR (und anderen SFRs) löscht man nicht durch ... |= (0 << XXX)
Sascha Weber schrieb: > ja - weil dum mit >>MCUCR = ((0<<ISC01) | (1<<ISC00)) > die die anderen Bits löschst, und damit auf LOW-LEVEL Trigger > umschaltest! > > Sascha ja, genau das habe ich gerade auch gemerkt ^^ so sollte es ja gehen oder ? Für INT0: MCUCR &= ((0<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10)); Für INT1: MCUCR &= ((1<<ISC01) | (1<<ISC00) | (0<<ISC11) | (1<<ISC10));
Johann L. schrieb: > Beim Umschalten kann evtl ein IRQ-Flag gesett werden, so daß direkt nach > der ISR eine "Schein-IRQ" getriggert wird. Also entsprechende Flags nach > Umsetzen von MCUCR löschen. > > Bits in MCUCR (und anderen SFRs) löscht man nicht durch > ... |= (0 << XXX) nur war da kein Oder vor dem Gleichhaltszeichen
nein - du musst mit AND nur die zu löschenden Bits ausmaskieren, und mit OR die anderen wieder setzen. Sascha
Sascha Weber schrieb: > nein - > du musst mit AND nur die zu löschenden Bits ausmaskieren, und mit OR die > anderen wieder setzen. > > Sascha ok, also meinst du der schreibt das SFR, welches zuvor so aussah MCUCR = ((1<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10)); mit MCUCR &= ((0<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10)); um so das dort nachher folgendes drin steht ? MCUCR = ((0<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10));
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.