Forum: Mikrocontroller und Digitale Elektronik UART eingabe (hTerm)


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Gast199 G. (Gast)


Angehängte Dateien:

Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Ich sehe nicht, wo Du den empfangenen String nullterminierst.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
-3 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


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

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht 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.

: Bearbeitet durch User
von Gast199 G. (Gast)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-4 lesenswert
nicht 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)


Bewertung
-4 lesenswert
nicht lesenswert
Noch ein Tip hinterher:
Verwende die rekursive Berechnungsmethode. Das gibt Extrapunkte auf 
Mikrocontrollern!

von Eberhard H. (sepic) Benutzerseite


Bewertung
2 lesenswert
nicht 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. (stefanus)


Bewertung
2 lesenswert
nicht 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.

: Bearbeitet durch User
von STK500-Besitzer (Gast)


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

von Johannes R. (johannesr)


Bewertung
-2 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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. (stefanus)


Bewertung
1 lesenswert
nicht 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. (stefanus)


Bewertung
2 lesenswert
nicht 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)


Bewertung
-2 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.