Forum: Mikrocontroller und Digitale Elektronik interrupt in c


von Jörg (Gast)


Angehängte Dateien:

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

von Uwe B. (Gast)


Lesenswert?

Globale Interruptfreigabe ???

#asm("sei") ?

MfG  Uwe

von Jörg (Gast)


Lesenswert?

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

von OldBug (Gast)


Lesenswert?

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

von Jörg (Gast)


Lesenswert?

was genau willst du mir jetzt damit sagen?
Ich kann damit nix anfangen...sorry!

von Jörg (Gast)


Lesenswert?

wie soll ich denn die bits korrekterweise setzten, mit welchen Befehlen
oder mit welcher Syntax?

von Jörg Wunsch (Gast)


Lesenswert?

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();

von Jörg (Gast)


Lesenswert?

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

von OldBug (Gast)


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

von Jörg (Gast)


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

von Jörg Wunsch (Gast)


Lesenswert?

Standard-C:

foo |= bar;

ist die Kurzform von:

foo = foo | bar;

von Jörg (Gast)


Angehängte Dateien:

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

von Jörg Wunsch (Gast)


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.

von Jörg Wunsch (Gast)


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;
}

von Jörg (Gast)


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

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
Noch kein Account? Hier anmelden.