mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik interrupt in c


Autor: Jörg (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Uwe B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Globale Interruptfreigabe ???

#asm("sei") ?

MfG  Uwe

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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..

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Jörg (Gast)
Datum:

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

Autor: Jörg (Gast)
Datum:

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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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();

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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???

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Standard-C:

foo |= bar;

ist die Kurzform von:

foo = foo | bar;

Autor: Jörg (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.