Es geht um eine einfache Division zweier Zahlen. Ich habe das Ganze in C realisiert. Ist die Zahl, mit der dividiert wird größer als 4 führt das zu einem Komplettstillstand im Mikrocontroller. Hier ist ein Ausschnitt des entsprechnden Programms. Da Ziel ist besteht darin eine Zahl auf ein Zahlendisplay auszugeben. Das Problem besteht darin, die auszugebende Zahl in ihre Bestandteile (Einer, Zehner usw.) aufzuspalten. int main(void) { char z,z2,z3,e1,e2,e3; outp(255,DDRA); outp(255,DDRD); outp(255,DDRC); z=1; z2=1; for(;;) { z++; /* Folgende Zeilen stellen das Problem dar. e1=z-((z/10)*10); //Die "Einer" einer dreistelligen Zahl werden ermittelt e2=z/10-((z/100)*10); //Die "Zehner" einer dreistelligen Zahl werden ermittelt e3=z/100; //Die "Hunderter" einer dreistelligen Zahl werden ermittelt */ idle(100); outp(z2,PORTC); //Hier tritt der Fehler auf! zahlausgeben(0,e3,0); idle(100); zahlausgeben(1,e2,0); idle(100); zahlausgeben(2,e1,0); } }
Wofür ist eigentlich z2 da? Ausßer einer einmaligen Initialisierung wird damit doch nichts gemacht? Du solltest statt char z,z2,z3,e1,e2,e3; lieber unsigned char z,z2,z3,e1,e2,e3; schreiben.
Ich hatte bereits unsigend vor der Variablendeklaration stehen, ohne Erfolg. Auf die einzelnen Variabeln müsst ihr glaube ich nicht näher eingehen. Es ist wirklich nur ein billiges Testprogramm. Tatsache ist mein geschildertes Problem. Dafür muss es doch eine einfache Erklärung geben, oder?
Der Fehler liegt nicht immer da, wo man ihn vermutet. Wie sieht denn Deine Funktion zahlausgeben(0,e3,0); aus?
Der Fehler kommt auch zustande, wenn ich den Funktionsaufruf weglasse. Der Mikrocontroller hängt sich im Grunde genommen an der Ausgabe des errechneten Wertes an den Port. (Siehe Kommentar im Quellcode)
Ja aber bei outp(z2,PORTC); //Hier tritt der Fehler auf! wird z2 doch gar nicht berechnet! z2 ist mit 1 initialisiert.
Da hast du natürlich Recht. Denke dir einfach die Variable e2 an diese Stelle. Es kommt das gleiche bei raus.
Moinsen, kann dein Problem leider auch nicht lösen, aber ich sitzte jetzt seit 10 min vor deinem Code und komme einfach nicht darauf wie du damit irgendwelche Dezimalstellen berechnest?! e1 und e2 sind doch immer NULL - oder bin ich zu blöde??? Ich weiß es geht nicht darum aber um was geht es denn... schreib doch einfach mal ne Konstante (in deinem Fall 1) in den Funktionsaufruf und ziehe den aus der for-Schleife der muss ja scheinbar eh nicht mehrfach aufgerufen werden. Ausserdem ist mir nicht ganz klar, warum das ein Problem mit dem dividieren seien soll? Fragen über Fragen ich mach mir mal nen Wein auf in diesem Sinne Prost
Hi Björn, zu Deinem Zeitpunkt war meine Wein leider schon alle :-( Alles in Allem muß ich sagen, daß ich froh bin, meine AVRs nur in Assembler zu programmieren. Ich verfolge schon eine Weile die ganzen Probleme mit diversen freien C-Compilern. Das ist ein gewagtes Spiel, das ich nicht spielen möchte. Ich schmeiße das Handtuch bei obigem Problem.
Mahlzeit, zu Deinem Problem mit den Einern, Zehnern, ...(stimmt e2 überhaupt?). Mach es doch einfach mit der Modulo-Division. einer = ergebnis%10; zehner = (ergebnis/10)%10; .. Gruß Marcel
Hi mal davon abgesehen das man outp() nicht mehr verwenden sollte kan ich keinen Grund entdecken warum dein code nicht funktionieren sollte. Kannst du mal ein Stück Code posten das den Fehler aufweist und compiliert werden kann. BTW: Das e1=z-((z/10)*10); zu e1=0; optimiert wird ist dir klar? Matthias
Dass der Compiler den Code so stark optimiert bis am Ende der Rechnungen jeweils 0 raus kommt, wusste ich nicht. Ich hatte gehofft, dass alles schön nach der Reihenfolge abgearbeitet wird. Es folgt ein für sich lauffähiges Testprogramm. Darin sollte mein Problem eigentlich deutlich werden. #include <io.h> #define F_CPU 8000000 void idle(unsigned int milli) { unsigned int z,z2; for(z=0;z<milli;z++) for(z2=0;z2<(F_CPU/1000);z2++){/*waiting 1 Millisec*/} } int main(void) { unsigned int a,b; outp(255,DDRC); a=1; for (;;){ a++; if (a == 2500) a=1; b = a/10; //Setzt mal spaßenshalber statt "10" "4" ein. Ihr werdet sehen, dass bei diesem Wert alles vollkommen problemlos läuft. outp(b,PORTC); idle(100); } }
Moinsen, also ich habe den Code mal bei mir in den CCS (PIC) reingehauen und da läuft das Ding (in VC++ auch). Wie kommst du denn darauf das es da zu Absturß kommt? Hast du das simuliert oder richtig in einen uC gebrannt? Du darfst nicht vergessen das eine Division durch eine Zahl 2^n (also 4, 8, 16 ...) nur einfache Schiebeoperationen ( nach rechts schieben) sind und das geht relativ fix. Wobei wenn du durch 10, 11 , oder 17 teielst muss der Compiler doch einiges mehr an Code umsetzten. Das dauert halt.....(is ja wohl ein 8-Bit uC) Schau dir doch mal dein Assemblerlisting an. Wenn du den Code simuliert hast, dann führe ihn nicht im Einzelschrittmodus aus sondern setzte einen Breakpoint auf outp(b,PORTC). Mal sehen ob's dann klapp In diesem Sinne Hummel, Hummel
Hi compiliert für einen ATmega16 funktioniert dein Code. dito für einen AT90S8515 (aktueller WINAvr) Matthias
Ich habe in meiner Verzweiflung den Chip (es war ein ATmega 16) mit einem anderen ausgetauscht. Nachdem dies auch nichts brachte steckte ich den Chip wieder zurück, und da o Wunder ging es auf einmal. Ich kann mir das absolut nicht erklären. Denn wäre etwas an der Hardware defekt gewesen hätten ja eigentlich deutlich mehr Störungen anfallen müssen. Wie auch immer, jetzt läuft alles. Euch vielen Dank für die Tips. Übrigends funktionieren unten stehende Code zur Berechnung der Dezimalwerte so wie ich es mir gedacht habe. Nix da mir 0! e1=z-((z/10)*10); //Die "Einer" einer dreistelligen Zahl werden ermittelt e2=z/10-((z/100)*10); //Die "Zehner" einer dreistelligen Zahl werden ermittelt e3=z/100; //Die "Hunderter" einer dreistelligen Zahl werden ermittelt
JAAAA Schande über mein Haupt ist ja ein int und kein Gleitkomma.... Ich sach ja vielleicht bin ich zu DOOF. Das darf der Compiler ja garnicht optimieren. in diesem Sinne
Ich bin in C noch nicht so bewandert. Du hast natürlich Recht, dass es mit dem Divisionsrest einfacher geht.
So ein Problem hatte ich auch schon mal. Allerdings in ASM. Ich hab Tagelang den Fehler gesucht warum mir der Prozessor an einer bestimmten Stelle abschmiert. Im Programm konnte ich keinen Fehler finden und der Prozessor war auch OK. Nach drei Tagen hab ich dann den Fehler dann gefunden. Ich hatte eine kaum sichtbare Lötbrücke auf der Platine. Wenn ich den Port auf High gesetz habe, habe ich den dadurch gegen Masse kurzgeschlossen und die Spannung ist kurz zusammengebrochen --> Reset. Vielleicht war´s so etwas? Steffen
Ich hatte das Glück das Starterboard gesponsert bekommen zu haben. Und da ist eine nicht sichtbare Lötbrücke unwahrscheinlich. Außerdem war mein Problem ein rein mathematisches. Ich vermute, dass bei den Standarteinstellungen des AVRs irgendetwas faul war. Wirklich rausfinden werde ich es wohl nie.
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.