mikrocontroller.net

Forum: Compiler & IDEs Interrupt - falscher Rücksprung ?


Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Problem mit der Nutzung von Interrupts. Ich habe schon
länger daran rumprobiert und bin jetzt zur einfachsten Variante (siehe
unten) übergegangen. Das ganze soll eigentlich nur nach kurzer Zeit den
Ausgang von Aus auf An schalten.
Der Interrupt wird auch ausgelöst und der Ausgang kurzzeitig auf An
gesetzt - gleich danach wird das aber zurückgesetzt und der Ausgang
wieder Low gelegt.
Ich habe so die Vermutung, dass entweder nach dem Interrupt ein Reset
ausgeführt wird oder aber der Rücksprung aus dem Interrupt nicht klappt
- würde er vor die Funktion "einstellen" springen, würde der Ausgang
ja wieder low gelegt.

Ich wäre wirklich über jede Hilfe sehr dankbar.

Code:
#define _AVR_ATmega169_

#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

void
einstellen (void)
{
  CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0);
  CLKPR = (0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(0<<CLKPS0); //Clock
geteilt durch 64

  DDRB = (1<<DDB6); //Pin7 an B auf Output
  PORTB = (0<<PB6); // und inaktiv

  TIMSK0 = (0<<OCIE0A)|(1<<TOIE0); //overflow enabled
  TCCR0A = (0<<WGM00)|(0<<WGM01)|(1<<CS02)|(0<<CS01)|(1<<CS00); //
prescaler 1024

  sei(); //globaler Interrupt an
}

SIGNAL (SIG_OVERFLOW0)
{
  PORTB = (1<<PB6);
}

int
main (void)
{
  einstellen ();
  for  (;;)
    ;
  return 0;
}

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define __AVR_ATmega169__

Das darfst Du nicht tun, Macros, die mit einem Unterstrich beginnen,
sind reserviert.  Dieser Macro wird intern generiert in Abhängigkeit
von Deiner -mmcu Anweisung.  Vermutlich liegt genau hier auch der
Pfeffer im Hasen: Du wirst kein -mmcu haben, so daß der Compiler/
Linker Dir die Runtime für irgendwas (AT90S8515 oder was auch immer
der Default ist) zusammenbasteln, so daß weder Interruptvektortabelle
noch Stack-Initialisierung auch nur ansatzweise passen.

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

danke für die Antwort - ich habe das jetzt rausgenommen und mit:

avr-gcc -mmcu=atmega169 test.c compiliert - danach dann noch das
HexFile erstellt:
avr-objcopy -j .text -O ihex a.out test.hex

Leider bleibt das Ergebnis das gleiche. Also wenn ich das auf den
Controller spiele, schaltet er den Ausgang kurz an und gleich wieder
aus.

Ist es möglich, dass er irgendwie falsch zurückspringt ?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich müßte im Datenblatt nachgucken, aber meiner Erinnerung nach kann
man bei ATmega169 den Watchdog per Fusebit einschalten.  Hast Du das
aus Versehen getan?

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab mal im Datenblatt geschaut - es ist möglich per Fusebit den Watchdog
zu aktivieren aber dazu hätte ich das WDCE bit setzen müssen und
eigentlich habe ich damit gar nix gemacht.
Der Code der oben steht ist alles, was ich nutze... wird das in einer
der Includedateien vielleicht gemacht ?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du wirfst hier ziemlich viel durcheinander.

Das Fusebit für den Watchdog heißt WDTON (in den high fuses) und hat
mit WDCE schlicht gar nichts zu tun.  Ob Du Deine Fusebits angefaßt
hast, hat nichts mit Deinem Code zu tun, sondern das tust Du vom
Programmiergerät aus.

Includedateien generieren durch bloßes Einfügen mit #include keinen
Code, können Dir also hier nichts geändert haben.

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

hm das stimmt, dass mit WDTON und WDCE hab ich jetzt durcheinander
gebracht, weil ich noch geschaut habe, ob ich den Watchdog vielleicht
selbst eingeschaltet habe.
Mir ist noch ein anderes Phänomen eingefallen. Ich hatte auch mal
versucht die Interruptroutine länger zu machen - also einfach mit einer
Schleife, die nur immer wieder den Assemblerbefehl nop ausgeführt hat.
Trotzdem hat sich aber die Zeit, die der Port an war nicht verändert.

Ich schreibe den Code auf den AVR mit AVRProg - also aus dem AVR Studio
4 heraus. Bisher hatte ich aber nie ein Problem und es hat eigentlich
immer alles so funktioniert, wie ich das wollte - dieses Problem habe
ich erst, seitdem ich Interrupts nutzen will.
Übrigens: wenn ich die Zeitspanne nach der der Interrupt kommen soll,
ändere, verhält es sich alles genauso (was doch eigentlich heisst, dass
es nur schwerlich am Watchdog liegen kann, weil ich doch nicht
gleichzeitig diese Zeitspanne verändere - jedenfalls nicht bewusst :)
)

Danke nochmal für die Hilfe.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht rufst Du ja testhalber einfach mal in der Hauptschleife
wdt_reset() auf?

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

ich habe jetzt mal in der Hauptschleife wdt_reset() aufgerufen - da hat
sich nichts verändert. Dann habe ich noch versucht bei der
Initialisierung den WDT auszuschalten über:
  wdt_reset();

  WDTCR = (1<<WDTCE) | (1<<WDE);

  /* Turn off WDT */
  WDTCR = 0x00;

Geändert hat sich aber auch nichts - er schaltet den Pin immer kurz auf
high und dann gleich wieder low.

Hast du noch irgend'ne andere Idee ?

Autor: Volkmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Niels,

Du schreibst:
| avr-gcc -mmcu=atmega169 test.c compiliert - danach dann noch das
| HexFile erstellt:
| avr-objcopy -j .text -O ihex a.out test.hex

Ich habe die Infos nicht hier, aber irgendwie vermisse ich den Linker.
Kann es sein, daß es daran liegt?

Volkmar

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, der Linker wird vom Compiler-Treiber (avr-gcc) aufgerufen, das ist
schon OK.

Ohne Debugger finde ich da jetzt auch kein Problem.

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Volkmar,

also so wie es bisher gemacht habe, dachte ich, dass er es von selbst
link und ich habe immer eine datei a.out bekommen. Ich habe aber jetzt
nochmal folgendes gemacht:

avr-gcc -g -Os -mmcu=atmega169 -c test2.c
dann
avr-gcc -g -mmcu=atmega169 -o test2.out test2.o
und
avr-objcopy -j .text -O ihex test2.out test2.hex

Wie ich das sehe ist meine .out Datei in der anderen Methode kleiner
gewesen dafür aber der Hex File grösser. Trotz diesem Unterschied hat
sich aber daran, was der Controller macht, nichts geändert.

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg

Was könnte ich denn da jetzt noch machen ?

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich hab dein Programm mal mit dem AVRStudio simuliert. Da funktioniert
er.

Matthias

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Mathias,

das habe ich auch gerade gemacht und es sieht wohl so aus, wie es soll
- aber was kann denn dann falsch sein ? So richtig ist mir die Sache
dann nicht klar.
Bei anderen Programmen hatte ich noch nie so ein Problem - nur seit ich
Interrupts nutzen will. Logisch ist das nicht, oder ?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmpf, was mir jetzt erst auffällt:

> TIMSK0 = (0<<OCIE0A)|(1<<TOIE0);

Du schaltest zwei Interrupts ein (output compare und overflow), aber
ich sehe nur einen Handler (overflow).  Damit schießt Dein output
compare ,,in die Luft'' und landet auf einem nichtzugewiesenen
Vektor.
Alle nichtzugewiesenen ISRs machen einen jmp 0.

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schreibe doch in das Output Compare eine 0 - also disable. Im
Datenblatt steht, dass es mit einer 1 eingeschaltet wird - also so wie
ich es gemacht habe, sollte eigentlich der Overflow an sein und der
Output Compare aus - oder nicht ?

Ich schreib mal schnell nen Handler dazu... ich hoffe, dass ist es :).

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm,

also ich habe einmal den "OUTPUT_COMPARE0" Handler dazu gemacht, da
hat sich nichts geändert.
Dann habe ich noch den Aufruf
> TIMSK0 = (0<<OCIE0A)|(1<<TOIE0);
zu
TIMSK0 = (1<<TOIEO);
geändert... also fasse ich das Output Compare nicht an.

Leider bleibt alles das gleiche.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach was, ich hatte sowieso nur Deine etwas umständlich ausgedrückte
Null-Anweisung übersehen (0 << irgendwas).  Klar, daß das dann nichts
ändert.

Nö, ohne Debugger keine Idee mehr.  Leider ist der ATmega169 in meinem
STK502 (oder wie das Teil heißt) nicht mehr gewillt, mit mir zu reden,
so daß ich das auch nicht mal schnell mit einem JTAG-ICE durchspielen
kann.  (Ich muß mal gucken, ob ich den ATmega noch parallel
programmieren kann, seriell reagiert er weder im STK500 noch in einem
08/15 Parallelport-Dongle.)

Autor: Niels Jacobsen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo (jetzt war die Seite aber lange down...),

ich wollte nur kurz sagen, dass ich es gefunden habe und einen Tipp
loswerden.
Nachdem Jörg das mit dem zusätzlichen InterruptHandler geschrieben hat,
dachte ich mir: egal, schreibste einfach für jeden Interrupt mal 'nen
Handler. Dann ging es und also habe ich nach und nach die Handler
wieder rausgenommen.
Zum Schluss hat sich rausgestellt, dass der PIN_CHANGE0 Interrupt
geworfen wurde... und natürlich nicht in meinem Code abgefangen.

Ich danke für jede Hilfe und vielleicht hilft meine Dummheit ja mal
einem anderen :)

Niels

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.