Hallo! Ich schaffs nicht, in einer schleife nem Struct einen Wert zuzuweisen. Der struct ist global definiert: struct { u08 high:8; u08 low:8; } servo1; Beim Init wird der Timer0 gestartet, welcher beim Überlauf die Compare-Werte des Timer1 setzt: OCR1H = servo1.high; OCR1L = servo1.low; Die Variablen werden vorher in der Main-Funktion mit: servo1.high = 16000/256; servo1.low = 16000%256; gesetzt. Soweit funktionierts noch. (Sowohl in AVRStudio als auch in Hardware) Im Hauptprogramm (main()) befindet sich jetzt folgende Schleife: while (1) { if (bit_is_clear(PINC,0)) { sbi(PORTC,2); servo1.high = 46; servo1.low = 224; } else { cbi(PORTC,2); servo1.high = 31; servo1.low = 64; } } Mit dieser Schleife kann ich bei drücken auf den Schalter an PINC,0 die LED an PORTC,2 ausschalten. Nur leider wird der Wert in meinem struct nicht verändert. Ein Blick in den ASM-Code zeigt: SBIC 0x13,0 Skip if bit in I/O register cleared RJMP PC+0x0003 SBI 0x15,2 Entspricht sbi(PORTC,2); RJMP PC-0x0003 CBI 0x15,2 Entspricht cbi(PORTC,2); RJMP PC-0x0005 d.h. gcc ignoriert einfach meine Zuweisung. Jetzt bin ich etwas ratlos. Ich hoffe, es kann mir von euch jemand helfen. Gruss, Andreas
Hi Andreas, vermutlich hat der GCC zuviel wegoptimiert. Werden die Werte in der Structure servo1 irgendwann nochmal verwendet? Versuch mal ein volatile vor die struct zu schreiben, also: volatile struct { u08 high:8; u08 low:8; } servo1; Vielleicht hilft das. Ansonsten poste mal bitte etwas mehr Code, das macht die Fehlersuche einfacher. Bye Daniel Jelkmann
Nur am Rande: Verwende in Zukunft nicht mehr sbi (...) und cbi (...), diese Ausdrücke sind veraltet. OCR1 kannst du direkte ansprechen, warum der Umweg über Low- und High-Byte?
Daniel hat Recht. Dein Code wurde wegoptimiert. War ja auch völlig sinnlos ;-) Alternativ zu volatile kannst Du gcc nach den Zuweisungen noch etwas mit den Werten arbeiten lassen. Denn nur wenn er den Eindruck hat, wirklich gebraucht zu werden, arbeitet er auch klaglos. Also z.B. folgendes anhängen: if ((servo1.low + servo1.high) > 200){ beschaeftigungstherapie(); } Gruß, Stefan
Btw: volatile struct { u08 high:8; u08 low:8; } servo1; Wo ist da der Sinn? Das ist keine "struct" in dem Sinne, sondern ein Bitfeld. Richtiger wäre da wohl eher: volatile struct { u08 high; u08 low; } servo1; ...IMHO...
Danke! Wurde tatsächlich wegoptimiert. volatile hat geholfen. Wundert mich nur etwas, denn ich hab im Makefile extra die optimierung auf 0 gestellt. @Mike: was wird statt sbi() und cbi() verwendet? Das konstrukt aus dem Wiki (PORTA &= ~(1<<MEINBIT);) find ich ziemlich unmerkbar, und sbi() wird doch schön in Assembler übersetzt. @OldBug: ...richtig!
Naja, unmerkbar oder nicht: es ist schlicht und einfach Standard-C ;-) Es gibt auf der Doku-Seite der avr-libc eine Seite mit abgekündigten funktionen, unter anderen sind da auch sbi und cbi vermerkt. Also besser jetzt schon mal an diese Schreibweise gewöhnen, in der nächsten avr-libc release wirds wohl laut Jörg Wunsch nicht mehr vorhanden sein...
Hi, du kannst dir ja definitonen machen fuer sbi und cbi. Mfg Dirk
Es ist aus den aktuellen Quellen bereits raus. U. a. wegen solcher
Mißverständnisse:
> "und sbi() wird doch schön in Assembler übersetzt."
Wurden sie nämlicht mitnichten zwangsläufig, da sie seit mehreren
Jahren bereits weiter nichts als Aliase für die Standard-C-
Bitmanipulationen waren. D.h. insbesondere, daß mit -O0 keine
Optimierung in SBI/CBI automatisch stattfand.
Mit -O>=1 erfolgt die Umsetzung, sofern die übrigen Randbedingungen
eine solche gestatten, d.h. nur ein Bit wird gesetzt oder gelöscht,
die Bitnummer ist zur Compilezeit bekannt/konstant, und das
IO-Register liegt im erreichbaren Bereich für SBI/CBI.
Hier mal mein Problem, vielleicht kann mir ja ein alter C-Hase sagen, was ich falsch mache: struct { char *MenuKey; unsigned char MenuButton; } Menu_1[20] = { "\t\t +++ Mainmenu +++\n\n", 0, "\t\t Menupunkt1\n\n", '1', "\t\t Menupunkt2\n\n", '2', "\t\t Menupunkt3\n\n", '3', "\t\t Menupunkt4\n\n", '4', "\t\t Exit\n\n"}, '5', }, Menu_2_1[20] = { "\t\t +++ Submenu 1 +++\n\n", 0, "\t\t Unterpunkt_1_1\n\n", '1', "\t\t Unterpunkt_1_2\n\n", '2', "\t\t Unterpunkt_1_3\n\n", '3', "\t\t Unterpunkt_1_4\n\n", '4', "\t\t Unterpunkt_1_5\n\n", '5', "\t\t Unterpunkt_1_6\n\n", '6', "\t\t Unterpunkt_1_7\n\n", '7', }; Unter Borland C geht das wunderbar, bei GCC krieg ich nur Fehlermeldungen... habs auch schon mit geschweiften Klammern um die einzelnen Einträge versucht...dann krieg ich "menu.inc:26: warning: initialization makes pointer from integer without a cast" als Fehler Hab in der Doku von der Lib nix gefunden. Hat da jemand noch ne andere Doku? Greetz OsiriS
Das Schachteln der Klammern ist laut Standard notwendig. Der `pointer from integer' ist wohl die herumlungernde '5' dort (zwischen dem Initializer von Menu_1[] und Menu_2_1[]). Aber sei gewarnt: der Krempel geht komplett in den RAM. In der fertigen Lösung wirst Du das wohl so nicht wollen. Außerdem verplemperst Du Platz, da Du den Arrays eine explizite Größe verpasst, diese aber nicht ausnutzt. Bitte für neue Fragen auch einen neuen Thread aufmachen, das hat mit dem ursprünglichen Thread ja absolut nichts mehr gemein.
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.