mikrocontroller.net

Forum: Compiler & IDEs Kein Zugriff auf globale Variable im Interrupt


Autor: Markus Wucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich habe hier einen ATtiny24 an dessen PortA eine 7-Segment-Anzeige und 
an Port B zwei LEDs hängen. Die 7-Segment anzeige soll immer im Kreis 
von 0-F zählen und die LEDs dazu blinken. Das ganze läuft über einen 
Timer-Interrupt, der die LEDs toggeln und den Wert für die Anzeige um 1 
erhöhen soll. Das klappt auch alles prima, bis auf die Erhöhung der 
Variablen, obwohl sie mit "volatile" deklariert ist! Die anzeige bleibt 
immer auf dem ersten Wert (7) stehen. Was mache ich falsch???

Vielen Dank für eure Hilfe!

Markus

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne Code schwer zusagen.

Ist die Variable wirklich Global und volatile?

volatile unsigned char uzibuz=0;

Gruß,
Dirk

Autor: Markus Wucher (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Sorry war grad zu doof den Code mitzuschicken.

Autor: Thomas Finke (thomas-hn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code sieht soweit eigentlich nicht schlecht aus (wenn ich nichts 
übersehen habe). Was evtl. noch sein könnte ist, dass deine globale 
Variable in dem Includefile für die Interruptverarbeitung nicht bekannt 
ist und daher nicht angesprochen werden kann?!? Aber müsste der Compiler 
dann nicht nen Fehler melden?

Was ich allerdings unschön finde ist der Funktionsaufruf innerhalb der 
Interruptroutine um die LEDs zu togglen. Realisiere das togglen doch 
einfach durch den Zweizeiler:

PORTB ^= (1 << LED1_POS);  //LED1 togglen
PORTB ^= (1 << LED2_POS);  //LED2 togglen

oder den Einzeiler:

PORTB ^= (1 << LED1_POS) | (1 << LED2_POS);  //LED1 & 2 togglen


Gruß,

Thomas

Autor: Markus Wucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab durch Thomas' Anregung ein bisschen mit den LEDs gespielt. Wenn 
ich versuche sie mit xor umzuschalten, muss ich sie in main ja 
initialisieren. und diesen 1. Zustand behalten sie dann. Man sieht nur 
ein ganz kleines Blitzen. Also irgendwie läuft mein Programm 
gelegentlich von vorn los, kann das sein?? oder ich häng irgendwo? Das 
würd auch das 1. Problem erklären.

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du den watchdog und brown out mal geprüft? Wie ist der Interrupt 
zeitlich eingestellt?

pumpkin

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tipp: Verwende eine temporäre Variable zur Ausgabe.

Statt
while (1) {
  count &= 0x0f;
  PORTA = ~seg_code[count];
  }
unsigned char temp;

while (1) {
        temp = count;
  temp &= 0x0f;
  PORTA = ~seg_code[temp];
  }
denn zwischen "count &=" und der Ausgabe auf PORTA kann die ISR 
zuschlagen.

Zum Problem:

Ich nehme mal an der Counter wird nicht richtig initialisiert. Kann 
jetzt nicht nachsehen, aber der Tiny45 kann doch sicherlich den CTC 
Mode?!
Für solche Aufgaben (regelmäßige Interrupts) ist der besser geeignet.

Werner

Autor: Thomas Finke (thomas-hn) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut Datenblatt müsste der Timer eigentlich so funktionieren wie Markus 
das macht. Ich hab im Datenblatt aber gerade noch die folgenden zwei 
Sätze gefunden:

Modifying the counter (TCNT1) while the counter is running introduces a 
risk of missing a compare match between TCNT1 and one of the OCR1x 
Registers.

Writing to the TCNT1 Register blocks (removes) the compare match on the 
following timer clock for all compare units.

Deine Programmzeile

TCNT1=0; //Timer wieder starten

in der Interruptroutine startet den Timer ja nicht neu, sondern setzt 
den Zählerstand des Timers nur wieder auf 0. Versuch mal vor diesem 
Schreibzugriff auf den Timer diesen anzuhalten und direkt nach dem 
Schreibzugriff wieder zu starten.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define __AVR_ATtiny24__

You are not supposed to do this!

Symbole, die mit zwei Unterstrichen anfangen sind (sofern nicht
ausdrücklich durch die Dokumentation authorisiert) für dich als
Endanwender tabu.

Da du das da obendrüber geschrieben hast, lässt mich das ganz
stark vermuten, dass du vergessen hast, beim Compilieren und
beim Linken -mmcu=attiny24 mit anzugeben.  Wenn du das nämlich
ordnungsgemäß machst, generiert der Compiler nicht nur ordentlichen
Code für deinen ATtiny24, sondern der Präprozessor kennt auch den
obigen Macro.  Wenn du das beim Linken auch noch mit dabei hast,
bekommst du zur Belohnung sogar noch die passende Interruptvektor-
tabelle für deinen ATtiny24 statt die für einen AT90S8515...

Autor: Markus Wucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab gerade das Symbol _AVR_ATtiny24_ weggemacht, und im Makefile MCU = 
attiny24 eingetragen.
Allerdings kann er jetzt gar nicht mehr kompilieren, da:
unknown MCU 'attiny24' specified
Known MCU names:
...
...

..nur kein tiny24

Hab ich da ne zu alte avr-libc, oder muss ich was anderes wählen? 
(vorher war avr2 eingestellt, dann kennt er aber auch eine Symbole des 
tiny24, eben nur durch das Symbol _AVR_ATtiny24_ )

Danke für eure Tipps!

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hab ich da ne zu alte avr-libc

Die gesamte Toolchain ist dann offenbar zu alt.  Wenn's denn ,,nur''
der Compiler wäre (die avr-libc aber den Prozessor kennt), könnte dir
der Trick mit dem _AVR_ATtiny24_ ja noch helfen, aber dann müsstest
du den Linker mit der Hand aufrufen, damit die crttn24.o ordentlich
gelinkt wird.

Autor: Markus Wucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab mir da irgendwie gar keine Gedanken über das Alter der Toolchain 
gemacht, weil ichs in Ubuntu aus dessen Repositories installiert hab. 
Aber hier ist glaub alles bisschen alt. simulavr kennt z.B. fast gar 
nix... Werd nächste woche mal alles auf den neuesten Stand bringen, dann 
wirds wohl klappen. Danke!

Gruß Markus

Autor: Frank Jonischkies (frajo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im aktuellen Ubuntu 7.04 ist AVR Libc 1.4.5 und GCC 4.1.0 dabei.

Autor: Markus Wucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt tut's wie gewünscht, vielen Dank. Habe die "cdk"-Pakete von 
sourceforge installiert.
Mit den ubuntu-paketen gings nicht, da kennt avr-gcc keinen attiny24.

Grüße Markus

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.