Hallo! Habe mal ein Frage. Habe michmal mit Interrupts beschäftigt, und es funktioniert nicht so wie ich das gerne hätte, bzw. gar nicht. Hab ein Programm geschrieben das einfach per interrupt eine LED anschalten soll (an PORTB). Macht so keinen Sinn, aber ich will mich da ja auch nur mal reinarbeiten. Der Interrupt soll durch den überlauf von counter/timer0 ausgelöst werden. Vielleicht kann mir ja jemand sagen warum das so nicht funktioniert wie ich mir das ausgedacht habe. mfg Jörg
Ja scho, aber das müsste ich eigentlich mit der Zeile outp(0x80,SREG); //Global interrupt enable erschlagen. Oder täusche ich mich da? Ist übrigens ein Atmega8..
outp/inp outb/inb sind "dperecated"... Ums mit Jörg Wunsch's Worten zu sagen: Nicht mehr benutzen! Und auch keine "magic numbers", alle bits sind per Makro definiert... Gruß, Patrick...
wie soll ich denn die bits korrekterweise setzten, mit welchen Befehlen oder mit welcher Syntax?
Daß Du 1.) outp() nicht benutzen sollst, sondern wenn schon, dann SREG = foobar; 2.) besser SREG |= _BV(SREG_I); schreiben solltest, aber 3.) noch besser einfach sei();
Tja, tut mir leid, aber das ist mir im Moment etwas zu hoch, bzw. diese SREG Sache ist mir eben neu. SREG |= _BV(SREG_I); --> Bedeutung???
Damit manipulierst Du NUR das Bit "SREG_I" des SREG. _BV steht für "bit value" und Maskiert das angegebene Bit. Hier wird eine Oderverknüpfung des Inhalts von SREG mit dem Bit SREG_I vorgenommen! Gruß, Patrick...
Aha, hab ich glaub verstanden. Also _BV()schreibt mit eine Maske, in dem Fall eben 10000000 , und das ganze wir dann mit dem ganzen Register SREG "verOdert" um die anderen bits nicht zu verändern. Richtig? Aber wieso "|=" und nicht nur "|" Na ja ich hoffe es stimmt wenigstens so etwa, ich muss mich für heute abmelden,morgen ist ja auch noch ein Tag. Danke für eure Hilfe. Gruß Jörg
Au ja, hätte ich eigentlich wissen können! Danke. Also ich hab das jetzt mal ein bisschen umgeschrieben, funktioniert aber immer noch nicht. Woran liegts? Und kann ich irgendwie elegant auch mehrere Bits in einem Register, z.B. hier: TCCR0 |= _BV(CS00); TCCR0 |= _BV(CS01); beide Bits auf einmal setzen? ( TCCR0|= _BV(CS00&CS01)???) Oder wie macht man das? Jörg
Letzteres: TCCR0 |= _BV(CS00) | _BV(CS01); aber das ist nicht mehr wirklich elegant, da es (zumindest mit AVR-GCC) dann kein SBI mehr benutzen kann, sondern tatsächlich read-modify-write Zyklen generiert. Du solltest Dir halt in solchen Fällen überlegen, ob nicht stattdessen die Absolutzuweisung TCCR0 = _BV(CS00) | _BV(CS01); sinnvoller ist. Die paßt dann wieder in einen OUT Befehl.
Umm, ich gucke mir den Code gerade an... Was geht eigentlich nicht bzw. was mißt Du wo? Port B klingt mir auch ein bißchen danach, als könnte es mit dem ISP kollidieren... Ansonsten: schmeiß die outp()s raus. Hmm, welche Libraryversion hast Du überhaupt? Ach, wenn das wirklich alles ist, müßtest Du sackweise Compilerwarnungen bekommen, da Dir mindestens noch 1...2 Headerfiles fehlen. #include <avr/io.h> #include <avr/signal.h> #include <avr/interrupt.h> SIGNAL(SIG_OVERFLOW0) { PORTB = 0xff; } int main(void) { DDRB = 0xff; TIMSK |= _BV(TOIE0); TCCR0 = _BV(CS00) | _BV(CS01); sei(); for (;;) ; } Ist aber langweilig, alle Pins von Port B gehen sofort auf 1 und bleiben dort. ;-) Interessanter: SIGNAL(SIG_OVERFLOW0) { static unsigned char c; c <<= 1; if (c == 0) c = 1; PORTB = c; }
Hallo! Also es funktioniert nachdem ich den "signal" header eingebaut habe. komischerweise kamen überhaupt keine Fehlermeldungen, das war ja eben was mich etwas verwundert hat. Was deine Interrupt funktion angeht haste natürlich recht, deine ist schon interessanter. Da hab ich auch gleich die nächste Frage: if (c == 0) c = 1; warum genau brauch ich diese Zeile. Also mit c <<= 1; schiebe ich ja praktisch ne 1 durch die 8 Bit von char c, richtig? Was passiert dann wenn die 1 praktisch "hinten raus" geschoben wurde? Es fängt nicht automatisch wieder von vorne an, richtig? Brauch ich dazu die obige Zeile? Jörg
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.