UART!

Gast #325334
Lesenswert?

Hi liebe Gemeinede :)

Habe folgendes Program geschrieben um mit dem Pc zu kommunizieren.

#include <AT89x52.h>
#include <stdio.h>

sbit Led = P1^0;
unsigned char Text1[80] = "Senden eines Strings über S0!";
void uart_init (void)

{
 PCON = PCON | 0x80;
 SCON = 0x52;
 T2CON = 0x34;
 RCAP2H = 0xFF;
 RCAP2L = 0xD9;
}

void send_char(char z)
{
  SBUF=z;

  while(!TI);
  TI=0;
}

void send_text(char* text)
{
  int i=0;
  while(text[i] != 0x00)
  {
          send_char(text[i]);
    i++;
  }
}

void main (void)
{
 Led=0;
 uart_init();

 send_text(Text1);
 while(1);
}

Das klappt auch alles aber meine 1. Frage ist nu wie ich eine neue
Zeile beginnen kann?Mit \n gehts nicht!oder ich habs falsch gemacht.

Die zweite:
Wie kann ich z.B. einen Messwert ausgeben? Ich messe z.B. eien
Temperatur und will die am PC angezeigt haben.

 Azeige ->  Die Temperatur beträgt ......

Ok.Wie ich den Text sende weiß ich ja aber den Wert der Temp?
Vielen Dank für euer bemühen.

mfg Cri
Gast #325338
Lesenswert?

Das mit dem \n habe ich anscheinend gelöst. Habe mein SCON=0x50;
gesetzt.Also das TI nicht gesetzt und dann gings ABER ich bekomme nun
ne neue Zeil jedoch wird bei der nächsten Asugabe in die nächste Zeile
UND am Ende des vorrigen Texts weiter geschrieben.

Sieht sso aus:   Textausgabe
                            Textausgabe
                                       Textausgabe
                                                  Textausgabe

Also ich hab keine Ahnung was da los ist. Ihr vielleicht?
Mein Progi ist im Anhang!
Angehängte Dateien:
#325341
Lesenswert?

Das liegt daran, dass es hier verschiedene Standards gibt.
Das Zeichen '\n' ist ein Linefeed. Zu Deutsch: Zeilenvorschub.

Und genau das macht dein Terminal: Einfach nur einen Zeilenvorschub.
(So wie wenn du bei einer alten Schreibmaschine am Rad drehst und
einfach nur das Papier weitertransportierst).
Du möchtest aber, dass nicht nur ein Zeilenvorschub passiert, sondern
dass auch der (gedachte) Schreibmaschinen-wagen ans linke Papier-
Ende zurückfährt, damit die nächste Zeile wieder am linken
Rand anfängt.

Die Lösung von Kai macht genau das.
Die untersucht ob im Ausgabestring ein '\n' vorhanden ist
und sendet dann beide Zeichen: Zeilenvorschub plus
Schreibposition_an_den_linken_Rand setzen.

Im Englischen: Carriage return  (abegkuerzt CR) und
Line feed (abgekürzt LF)

Wenn du dir jetzt mal eine ASCII Tabelle zu Gemüte führst,
zb. die hier
http://www.torsten-horn.de/techdocs/ascii.htm
dann siehst du, dass neben 0x0A ein LF steht und neben 0x0D ein CR.
Jetzt weist du auch, was das bedeutet :-)

Bei vielen Terminals kann man auch einstellen, ob sie bei
einem Linefeed automatisch auch einen CR machen sollen, bzw.
umgekehrt. Daher die eingangs erwähnten verschiedenen Standards.
Gast #325342
Lesenswert?

0x0A oder auch ASCII-Code 10.
Es sorgt dafür, dass der Cursor eine Zeile tiefer rutscht.
Wie bei einer (mechanischen) Schreibmaschine: Da gab es so ein Rad mit
dem man das Papier zeilenweise hochschieben konnte.
Dann gab es noch das Carriage Return (auch Wagenrücklauf genannt):
dadurch wurde der Wagen wieder an den Zeilenanfang zurückgeschoben
(manchmal/meist wurde auch gleich das Papier um eine Zeile nach oben
verschoben).
Das sind alles Steuerbefehle aus der Zeit, als Fernschreiber noch
modern waren...

http://de.wikipedia.org/wiki/Ascii
Gast #325343
Lesenswert?

Welches Terminalprogramm benutzt Du,
resp. genauer welche Terminalemulation benutzt dein Terminalprogramm
??

VT100, VT52 oder was ..?

Wenn Du das festlegst dann schaue Dir übers Intenet einmal die Escape
Sequenzen für dieses Terminal an und setzte sie in deiner Software um.

Dus solltest dann natürlich wissen was ein CR 0Dh oder LF 0Ah ist...
#325344
Lesenswert?

> Das Zeichen '\n' ist ein Linefeed

Ooops. Das stimmt so nicht. Das Zeichen '\n' ist kein
Linefeed an sich. Aus C-Sicht ist nicht definiert ob das
jetzt einem LF, einem CR oder der Kombination aus beidem
entspricht. Normalerweise wird tief in den Innereien von C
festgelegt, welches Zeichen, bzw. welche Kombination benutzt
werden soll, wenn '\n' angetroffen wird. Das blöde ist nur:
Diese Festlegung muss auch mit dem tatsächlich benutzten
Terminal übereinstimmen, sonst gibt es einen Salat. Ein Terminal
kann man aber meist auf verschiedene Standards einstellen wodurch
erst recht wieder ein Salat entsteht, dann davon weiss die I/O
runtime wiederrum nichts (wenn man es nicht entsprechend eingestellt
hat). Oder wie TV-Kaiser sagen würde: Ein Teufelskreis.
Gast #325345
Lesenswert?

Danke Jungs. Also ich benutze das Tera Term und im Terminal setup habe
ich mal CR+LF gesetzt (waren aber auch gesetzt) und es ist noch immer
das selbe Problem. Habe es auch nur mit CR probiert aber das funzt auch
net.
Sollte ich das Progi (weiter oben im Thread) von Kai Riek (kairiek) am
besten verwenden?
Oder wie macht ihr das?
Gast #325347
Lesenswert?

Habe es mit dem Beispiel von Kai Riek gemacht und das klappt. Habe nur
dei ELSE-Bedingung löschen müssen dar er mir alles doppelt schrieb.
Code ist im Anhang.

Hat irgendwer einen Tipp für mich wie ich mein 2 Problem lösen kann?
Angehängte Dateien:
#325353
Lesenswert?

> Ok.Wie ich den Text sende weiß ich ja aber den Wert der Temp?

Der SSchlüssel liegt darin, dass du zunächst deinen Messwert
der ja als Zahl vorliegt in einen String übersetzen musst.
Diesen String verschickst du dann über bereits vorhandene Kanäle.

Die Umwandlung kann man auf mehrere Arten machen:
zb.

  char Buffer[10];
  sprintf( Buffer, "%d", Temp );

oder wenn dein System die Funktion itoa hat:

  char Buffer[10];
  itoa( Temp, Buffer, 10 );

ev. heist die auch _itoa() um anzuzeigen dass es sich
um eine Nichtstandardzahl handelt.

Oder du schreibst dir selbst eine Umwandlung: Zahl
mit fortgesetzten Divisionen durch 10 in die einzelnen
Stellen zerlegen und für jede Stelle den entsprechenden
ASCII Code schicken.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren