Hallo liebe Mikrocontroller-Community, ich muss für ein Projekt eine Fakultätsfunktion programmieren, die für eine eingegebene Fakultät alle Stellen im Hterm ausgibt. Die Eingabe klappt soweit,jedoch kann ich nur bis zu einem Dezimalwert von 255 eingeben (255! Fakultät). void uart_input () { while ( !(UCSRA & (1 << RXC)) ) { // Warten, bis Daten empfangen werden } fakultaet(UDR); } } Jedoch möchte ich meine Eingabe so, dass ich höhere Fakultäten eingeben kann und Eingabefehler filter (Nur Ganzzahlen und bis zu 4 Digits). Dazu habe ich mir überlegt die Empfangenen ASCII Zeichen in einem char string abzuspeichern und über die Funktion "atoi" wieder in einen Integer umzuwandeln. So war meine Idee: void uart_input () { char myArray[DIGITS] = {}; int x1=0; while(myArray[0]>='0'&& myArray[0]<='9'){ x1++; myArray[x1]=UDR; while ( !(UCSRA & (1 << RXC)) ) { // Warten, bis Daten empfangen werden } } int i = atoi(myArray); fakultaet(i); } Jedoch kommt nur Mist raus. Kann mir jemand da weiterhelfen?
Enver P. schrieb: > char myArray[DIGITS] = {}; > while(myArray[0]>='0' && myArray[0]<='9') { Das ist schon Unsinn. Du beginnst mit einer leeren Zeichenkette und wiederholst dann etwas so lange, wie das erste Zeichen eine Ziffer ist. Was hast du dir dabei gedacht? Dann liest du zuerst das UDR Register, und erst danach wartet du, dass etwas empfangen wurde. Das ist die falsche Reihenfolge. Was hier völlig fehlt, ist ein Check, ob zu viele Zeichen empfangen wurden. Wenn dein Puffer überläuft, wird irgend etwas passieren, nur nichts gutes, weil du das RAM durcheinander bringst.
Ich will einfach das char Array mit den eingegebenen Ziffern im hTerm befüllen. Jedoch habe ich kaum Erfahrung mit dem Mikrocontroller und weiß nicht wie ich das programmieren soll.
Enver P. schrieb: > und bis zu 4 Digits Fakultät einer 4-stelligen Zahl? Komplett ausgeschrieben? Du musst Zeit haben!
Also im microsoft visual studio kann ich fakultäten über 10000! berechnen lassen und in diesem Projekt müssen wir schauen wann unser skt500(atmega16) an seine Grenzen stößt.
253! ist bereits knapp 10^500 (mehr kann mein Taschenrechner nicht). Der ATmega16 hat 1024 Bytes RAM.
Enver P. schrieb: > Jedoch habe ich kaum Erfahrung mit dem Mikrocontroller und > weiß nicht wie ich das programmieren soll. In dem Fall wird es dir viel leichter Fallen, die Programmiersprache auf einem PC zu lernen und das dort gelernte dann auf dem Mikrocontroller anzuwenden. Logisches Denken können wir hier im Rahmen einer Diskussion nicht vermitteln. Das fällt einem entweder vom Himmel zu, oder man lernt es durch üben, üben, üben. Hast du wenigstens einen Debugger für den Mikrocontroller? Wenn ja, dann führe das Programm Zeile für Zeile aus. Gucke dabei zu und schau auf die Inhalte der Variablen. Dann geht dir vielleicht ein Licht auf. So mache ich das immer, wenn ich gerade gar nicht checke, warum ein paar Zeilen nicht das tun, was sie sollen. Wenn nicht: herzliches Beileid. Ich hoffe, du hast zu Weihnachten Geld bekommen, um dir einen Mikrocontroller + Debugger zu kaufen. Zum Beispiel ein Nucleo-F303RE oder Nucleo-F073RZ Board für 15-20 Euro.
hab leider keinen debugger. void uart_input () { char myArray[DIGITS] = {}; char RXChar; int index=0; while(1) { while ( !(UCSRA & (1 << RXC)) ) { // Warten, bis Daten empfangen werden } RXChar = UDR; if(RXChar >='0' && RXChar <= '9' && index<4) //Fehler Abfrage { myArray[index++]=RXChar; }else if(RXChar == 13) // Wenn Enter gedrückt wird { int i = atoi(myArray); //wandelt char Array in integer um if (i<= FAC_MAX) // Wenn fakultät kleiner als 500 { fakultaet(i); } else { index =0; myArray[index]='\0'; } } } } mir wird jetzt gar nichts ausgegeben. Ist mein code immernoch unsinn?
Enver P. schrieb: > hab leider keinen debugger. Dann nimm, verdammt nochmal, den Simulator, damit geht das (mindestens) genau so gut.
Enver P. schrieb: > mir wird jetzt gar nichts ausgegeben. Ist mein code immernoch unsinn? Sag mal, du studierst WAS?! Du bist ja nicht mal in der Lage ein komplettes Programm hier reinzustellen. Ist dir klar, dass 9999! über 35000 Stellen haben wird.
Noch ein Tip hinterher: Verwende die rekursive Berechnungsmethode. Das gibt Extrapunkte auf Mikrocontrollern!
Enver P. schrieb: > ich muss für ein Projekt eine Fakultätsfunktion programmieren, die für > eine eingegebene Fakultät alle Stellen im Hterm ausgibt. Zunächst solltest du erst einmal abschätzen, wieviel SRAM zur Berechnung der Fakultät nötig ist. Das hängt stark vom verwendeten Verfahren und der Darstellung der Zahlen ab. Bei binärer Darstellung könnte man bei 1024 Byte SRAM des ATmega16 maximal das Ergebnis (mit allen Stellen) von 966! (2466 Dezimalstellen) darstellen (wenn ich mich nicht verschätzt habe). Bei BCD-Darstellung könnte man 2048 Ziffern darstellen bzw. maximal 824! (2047 Dezimalstellen). Da die Berechnung der Fakultät auch SRAM benötigt, ist es auf jeden Fall deutlich weniger. Für möglichst kurze Laufzeit habe ich auf einem ATmega1284 per GCC bis zu 1227! realisiert (per Assembler bis zu 1230!), allerdings dabei großzügig ein Byte pro Dezimalziffer verwendet und 4 vollständige Teilprodukte, die zum Ergebnis aufaddiert werden. Auch wurde deshalb keine serielle Schnittstelle für die Ein- und Ausgabe vorgesehen. Details siehe: http://www.led-treiber.de/html/fakultat.html Bei einer kompakteren Darstellung kommt man auf Kosten der Laufzeit mit weniger SRAM aus und kann entsprechend größere Fakultäten berechnen. Da die serielle Schnittstelle ebenfalls einiges an SRAM/Stack benötigt, würde ich zunächst die Fakultät nur von konstanten im Programm definierten Werten berechnen und nur die ersten Ziffern zur Kontrolle an freien Ports anzeigen. Erst wenn das klappt, kann man die Ein- und Ausgabe per serieller Schnittstelle dazu nehmen, aber dann halt nur entsprechend kleinere Fakultäten berechnen.
Enver P. schrieb: > mir wird jetzt gar nichts ausgegeben. Dann füge doch mal Debug-Meldungen hinzu die dir anzeigen, welche Teile durchlaufen werden. Hinter jedem while, if und else kannst du solche Ausgaben einfügen. Dabei kannst du auch gleich die Inhalte wichtiger Variablen ausgeben, die für Entscheidungen/Ablauf des Programmes relevant sind. Die Einrückung ist immer noch schlampig. Das solltest du als erstes lernen. Gewöhne dir an, jede Ebene konsequent mit 4 Leerzeichen ein zu rücken. Also so:
1 | {
|
2 | ...
|
3 | ...
|
4 | {
|
5 | ...
|
6 | ...
|
7 | }
|
8 | ...
|
9 | ...
|
10 | }
|
Es gibt viele unterschiedliche Stile der Einrückung. Ich finde sie alle in Ordnung, solange man sich innerhalb eines Projektes konsequent an einen Stil hält. Das fehlt in deinem Fall.
erste Übung mit der seriellen Schnittstelle: Empfange ein Zeichen und sende es ander Absender zurück.
@Stefanus Zitat: "Die Einrückung ist immer noch schlampig." Da kann ich dir nur zustimmen!!! Aber man kann es auch freundlicher Ausdrücken. Im ganzen Thread lese ich dich nur Meckern. Anstatt große Töne zu spucken mit deinen 30.000 Beiträgen kannst du dem armen Kerl bei seinem, für dich Trivialen, Problem helfen. Mfg
Johannes R. schrieb: > @Stefanus > Zitat: "Die Einrückung ist immer noch schlampig." > > Da kann ich dir nur zustimmen!!! Aber man kann es auch freundlicher > Ausdrücken. Im ganzen Thread lese ich dich nur Meckern. Anstatt große > Töne zu spucken mit deinen 30.000 Beiträgen kannst du dem armen Kerl bei > seinem, für dich Trivialen, Problem helfen. > Volltreffer. Er nimmt aber hier nur fakultativ teil.
Enver P. schrieb: > mir wird jetzt gar nichts ausgegeben. Ist mein code immernoch unsinn? Es fehlt noch devzero schrieb: > Ich sehe nicht, wo Du den empfangenen String nullterminierst.
Johannes R. schrieb: > Anstatt große Töne zu spucken mit deinen 30.000 > Beiträgen kannst du dem armen Kerl bei > seinem, für dich Trivialen, Problem helfen. Ich würde gerne deinem positiven Beispiel folgen, sehe hier aber nichts dergleichen.
Stefan ⛄ F. schrieb: > Ich würde gerne deinem positiven Beispiel folgen, sehe hier aber nichts > dergleichen. Der hat sich doch erst gestern angemeldet. Wohl nur um meckern zu können. Genauso wie der TO sich auch gestern angemeldet hat um so erbärmlichen code hier zu zeigen. Seine Fragen sind völlig ohne Grundlage und zielen nur darauf ab ihm seine Übungsarbeit zu erldedigen, dass ich mich da dran nicht beteilige.
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.