interrupt in c

Gast #84878
Lesenswert?

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
Angehängte Dateien:
Gast #84886
Lesenswert?

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...
Gast #84887
Lesenswert?

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
Gast #84889
Lesenswert?

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
Angehängte Dateien:
Gast #84890
Lesenswert?

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.
Gast #84891
Lesenswert?

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;
}
Gast #84892
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren