Forum: Mikrocontroller und Digitale Elektronik UART eingabe (hTerm)


von Gast199 G. (Gast)


Angehängte Dateien:

Lesenswert?

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?

von devzero (Gast)


Lesenswert?

Ich sehe nicht, wo Du den empfangenen String nullterminierst.

von Stefan F. (Gast)


Lesenswert?

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.

von Gast199 G. (Gast)


Lesenswert?

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.

von Nick M. (Gast)


Lesenswert?

Enver P. schrieb:
> und bis zu 4 Digits

Fakultät einer 4-stelligen Zahl? Komplett ausgeschrieben?
Du musst Zeit haben!

von Gast199 G. (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

253! ist bereits knapp 10^500 (mehr kann mein Taschenrechner nicht). Der 
ATmega16 hat 1024 Bytes RAM.

von Stefan F. (Gast)


Lesenswert?

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.

von Gast199 G. (Gast)


Lesenswert?

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?

von c-hater (Gast)


Lesenswert?

Enver P. schrieb:

> hab leider keinen debugger.

Dann nimm, verdammt nochmal, den Simulator, damit geht das (mindestens) 
genau so gut.

von Nick M. (Gast)


Lesenswert?

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.

von Nick M. (Gast)


Lesenswert?

Noch ein Tip hinterher:
Verwende die rekursive Berechnungsmethode. Das gibt Extrapunkte auf 
Mikrocontrollern!

von Eberhard H. (sepic) Benutzerseite


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

erste Übung mit der seriellen Schnittstelle:
Empfange ein Zeichen und sende es ander Absender zurück.

von Johannes R. (johannesr)


Lesenswert?

@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

von Och, hör off jezz (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Nick M. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.