Kein Zugriff auf globale Variable im Interrupt

Gast #581517
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
Persönliche Seite #581532
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
Gast #581538
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.
Gast #581609
Lesenswert?

Tipp: Verwende eine temporäre Variable zur Ausgabe.

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

3
while (1) {
4
        temp = count;
5
  temp &= 0x0f;
6
  PORTA = ~seg_code[temp];
7
  }
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
Persönliche Seite #581624
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.
Moderator Persönliche Seite #581692
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...
Gast #582019
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!
Gast #582955
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

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