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
Ohne Code schwer zusagen. Ist die Variable wirklich Global und volatile? volatile unsigned char uzibuz=0; Gruß, Dirk
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
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.
Hast du den watchdog und brown out mal geprüft? Wie ist der Interrupt zeitlich eingestellt? pumpkin
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
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.
> #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...
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!
> 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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.