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.
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.
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.
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.
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.
@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.