Hallo, Der Code auf meinem AT90s2313 sieht prinzipiell so aus: int main (void) { init (); do { //tut was } while (1); } Anzunehmen ist nun, dass die do/while Schleife immer wiederholt wird, während die init-Funktion nur einmal aufgerufen wird (Abgesehen vom timerintrrupt). Nun führt der uc allerdings die init-Funktion in unregelmässigen Zeitabständen aus (.5 - 10s). Das riecht schwer nach unbeabsichtigtem Reset, doch sehe ich mit KO keine Änderung des Reset-Pins. Den Watchdog timer habe ich ausgeschaltet. Kann mir da jemand weiterhelfen? Gruss Ralf
naja, da der rest nich dasteht: hast du die möglichen interruptfälle abgedeckt?selbst wenn nur dasteht SIGNAL(SIG_OVEFLOW0) { } und signal.h miteinbinden gruß peter
Es gibt einen Handler für unerwartete Interrupts, das sollte also nicht das Problem sein...
Worauf ich damit hinaus wollte: gerade weil es diesen Handler gibt, braucht man nicht die ganzen Deklarationen für jeden möglichen oder unmöglichen Interrupt im Source vorzuhalten. Benötigt man keinen Interrupt, dann braucht man auch die avr/signal.h nicht. Allerdings darf man dann auch kein GIE-Flag setzen.
Hi, vielleicht sollte Ralf mal den gesamten Code posten. Er erwähnte einen Timerinterrupt und, falls er den außer Acht lässt, resetet das Ding aus Verzweiflung, weil es nicht weiß wohin mit sich....oder irr ich mich? Bin ja auch noch ein Greenhorn ;)
Ich vermute, es wird das übliche Problem werden: Schreibfehler im Namen des Vektors.
Hallo! Danke für die vielen Antworten! Ich sende mal den Code als Anhang - vielleicht seht ihr dann mehr...
Hi! Kann es sein, dass der Compiler das 'do {...} while(1);' wegoptimiert und der µC den Inhalt des kompletten Code-Speichers ausführt? Verwendet man nicht überlicherweise 'while(1){...}' ? mfg Reinhard
Wieso ein Bug? AFAIK is es bei den 8051er Compilern so... warum also nicht auch beim avr-gcc? mfg
Auch wenn es bei den 8051er Compilern tatsächlich so sein sollte, ändert das nichts daran, daß es ein Bug wäre. do { ... } while (1); besagt eindeutig, daß der Block in einer Endlosschleife auszuführen ist, genauso wie while(1) { ... } oder for (;;) { }. Wegoptimiert darf da höchstens dann was werden, wenn in der Schleife effektiv nichts passiert. Also für do { /* nix */ } while (1); muß der Compiler keinen Code erzeugen, auch nicht für int main(void) { int foo; do { foo++; } while (1); } (das Ergebnis von `foo' kann nirgends mehr benutzt werden), wohl aber für int foo; extern int foobar(void); int main(void) { do { foo++; foobar(); } while (1); } da hier für den Compiler nicht ersichtlich ist, daß die externe Funktion foobar() keinerlei Seiteneffekte bezüglich foo hat.
Momentan habichs mit Optimierungsstufe 's' compiliert. Mit Stufe 1,2,3 geschieht dasselbe. Der Stufe 0 - Code ist zu gross für den uc. Mit der 'while(1){...}' Methode dasselbe. Die compilierte Hex-Datei der mainfkt. mit Stufe 's' und 'while(1){...}' ist im Anhang - vielleicht seht ihr etwas...
Ich glaub, ich hab das Problem gelöst! Es war tatsächlich kein softwarproblem -> einfach ein 1uF C direkt in die Speisung des uC und nun gehts ohne Probleme. Die Spannung schwankte vorher scheinbar genug stark, dass der uC einen Reset auslösste... Danke für die vielen Antworten!
OK, nun kannst Du Dich zum Abschluß auch noch hinsetzen und all die seit 2 Jahren schon veralteten inp/outp/sbi/cbi rauswerfen. Teilweise wie hier: if (USR & 0x18) hast Du ja schon neue Syntax benutzt, warum dann nicht überall? In der nächsten `major' Version der avr-libc wird sich Dein Code sonst nicht mehr compilieren lassen -- auf dem avr-libc-1.1er Arbeitsstand schon jetzt nicht mehr. Da ich bei mir diesen Arbeitsstand fahre, werde ich notgedrungen auch irgendwann aufhören, Anfragen für Code, den ich nicht mehr compilieren kann, zu beantworten.
Tut mir leid, das war mir bis jetzt nicht bewusst. Ist das hier beschrieben? http://jubal.westnet.com/AVR/doc/avr-libc-user-manual/ Vermutlich bin ich zu blöd, aber wie sieht denn z.B. die neue Syntax für cbi(x,y) aus?
Naja, jubal.westnet.com war ein temporärer Standort. Wo geistert die URL denn noch herum? Ich weiß nicht, ob die noch aktuell gehalten wird. Offiziell ist http://www.nongnu.org/avr-libc/user-manual/index.html Beschrieben ist das soweit dort schon, insbesondere sind die alten Makros auch allesamt als `deprecated' markiert. Die Syntax für cbi(x, y) sieht in Standard-C so aus: x = x & ~(1 << y); oder kurz x &= ~(1 << y); Sollte in jedem besseren C-Lehrbuch stehen. ;-) Der cbi-Makro macht übrigens exakt das (insbesondere garantiert er Dir eben nicht, daß auch wirklich ein CBI herauskommt). Mit eingeschaltetem Optimierer und passenden Operanden kommt aber am Ende ein CBI heraus. Da der Konstrukt (1 << y) sehr häufig benöigt wird, bietet die avr-libc dafür den Makro _BV(). Du kannst das also auch als x &= ~_BV(y); schreiben.
Hallo, saublöde Anfängerfrage: Kann man statt x = x & ~(1 << y); nicht einfach x = (0 << y); schreiben? Dann würd´s mir viiiiiiel leichter verständlich werden. Gruß Lutz
Kannst du nicht! Das siehst du, wenn du dir einmal die einzelnen Schrite des Befehls ansiehst. (1<<y) -> Schiebt eine 1 an die Stelle y ~( ) -> An der Stelle y steht eine 0 an allen anderen eine 1 x & -> Und-Verknüpfung bei deiner Lösung würdest du eine 0 an die Stelle y schieben und dann x den den Inhalt 0%00000000 zuweisen. Damit wären alle gelöscht. Und selbst mit einen x &= (0<<y) würdest du alles löschen, weil 0 und irgendwas immer noch 0 ist. Mike
Danke Mike, Du hast recht, das ist nachvollziehbar. Würde dann eine ODER-Verknüpfung gehen wie x |= (0<<y); Wenn ich mich nicht wieder vertue (was leider sehr gut sein kann), dann bleiben die anderen Bits des Registers so wie sie sind (Wenn vorher eine 1 war: 1 ODER 0 = 1, wenn vorher eine 0 war: 0 ODER 0 = 0)und das Bit y wird durch das Bit-Shift auch 0. Wenn ich das jetzt nicht mit Java vermixe, dann wird doch erst der rechte Wert errechnet und dann dem linken zugewiesen. Oder ist die Reihenfolge doch anders, dann kann das gerade geschriebene natürlich Quatsch sein. Ich hoffe, daß ich mich jetzt nicht gerade restlos blamiert habe! Gruß Lutz
Wenn du eine 0 um y Stellen verschiebst und den Rest mit Nullen auffüllst, was kommt dann raus? Eine Null. Und etwas mit Null zu verODERn ist nicht sinnvoll ;)
Ein bißchen hast Du das schon. ;-) Der indirekte Beweis ist hier wohl einfacher. Der Ausdruck "(0 << y)" ergibt schlicht eine 0, mithin könntest Du gleich "0" schreiben. Wenn Du nun einen beliebigen Wert ODER 0 hast, kommt wieder der Wert selbst heraus, ergo ist das nicht, was Du haben wolltest.
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.