Forum: PC-Programmierung Bytes über Serielle Schnittstelle senden/empfangen


von achim (Gast)


Lesenswert?

Hallo,

ich beschäftige mich gerade damit, vom PC Daten an den MC (mega168) zu
schicken und dann wieder zum PC zurückzuschicken.

Ich habe dazu am PC mit C# ein Windowsprogramm geschrieben.

Das senden mehrerer Bytes an den MC ist kein Problem, da der
Eingangspuffer auf der PC Seite sehr groß ist. Der MC holt sich dann
seriell die Daten ab.

Wenn ich nun mehrere Bytes vom MC an den PC schicken will, weis ich
nicht, wie ich die dann seriell abfragen kann.

Als Beispiel schicken ich einen String mir 3 mal einem Byte.

Die C# Routine beim Empfangen lautet:

 serialPort1.Open();
 serialPort1.Read(b, 0, 3);
 serialPort1.Close();

b ist ein ByteArray der Größe 3.

byte[]

Eigentlich sollte nun das erste Byte in b[0], das zweite in b[1] und das
dritte an b[2] abgespeichert werden. Allerdings empfange ich nur ein
Byte  in b[0].

Kann es sein, dass der Pufferspeicher vom UART im MC nur ein einziges
Byte aufnehmen kann ?

Bin über Tipps sehr Dankbar !

Grüße

von Matthias L. (Gast)


Lesenswert?

>Kann es sein, dass der Pufferspeicher vom UART im MC nur ein einziges
>Byte aufnehmen kann ?

Das kommt auf dein Programm im µC an.

Poste das doch mal...

von einer (Gast)


Lesenswert?

Irgendwie verwechselst du Eingangs und Ausgangspuffer.
Geht es wenn du die Byte einzeln in einer Schleife empfängst?

von Bernd (Gast)


Lesenswert?

Hallo,
so ganz verstehe ich das auch nicht. Was klappt denn nicht.
Vom MC mehere Datenbytes schicken, oder mehrere Datenbytes im PC 
empfangen?
Gruss Bernd

von Severino R. (severino)


Lesenswert?

Du solltest die gleiche Frage nicht in verschiedenen Foren posten.

Beitrag "Bytes über Serielle Schnittstelle senden/empfangen"

von achim (Gast)


Lesenswert?

Also wenn ich die Bytes vom PC zum MC schicke, funktioniert es.
Hier der Code in C# :

        byte[] b = new byte[3];

            serialPort1.Open();
            serialPort1.Write(b,0,3);
            serialPort1.Close();

Es werden hierbei die drei Bytes im Byte-Array b[3] in den Puffer 
geladen.
Der MC holt sich die Daten dann seriell ab und speichert sie in das 
byte-array s[3] ab :

  while(1)
  {

  c = uart_getc();

    if ( c & UART_NO_DATA )
        {
        }
  else
        {
    s[x] = c;
      x++;

        }
   }

Ich benutze dabei die Funktion von Peter Fleury.
Ich kann dabei sehr viele Bytes losschicken, da der Ringpuffer eine 
einstellbare Größe hat.

Wenn ich nach demselben Gedanken die Bytes vom MC zum PC schicken will,
dann kommt immer nur ein Byte durch.
Die Abfrageprozedur in C# ist Timer gesteuert und fragt sehr viel öfter 
nach Daten ab, als gesendet werden.


Ein weiteres Problem habe ich noch:

Wenn ich vom MC zu PC Daten schicke, dann werden die von C# immer als 
ASCII Zeichen interpretiert.

Wenn ich beispielsweile eine 6 schicke, dann kommt eine 54 an. Diese 
könnte ich natürlich wieder irgendwie in die Dezimalzahl umwandeln, aber 
problematisch wird es bei Mehrstelligen zahlen.
Eine 12 zum Beispiel würde von C# zwei Plätze des Byte-arrays einnehmen:

b[0]=49
b[1]=45

Wie kann ich das nun übergehen, bzw. die Zahlen wieder zusammenfügen ?

von Daniel F. (df311)


Lesenswert?

achim wrote:
> Die Abfrageprozedur in C# ist Timer gesteuert und fragt sehr viel öfter
> nach Daten ab, als gesendet werden.
>
warum denn timer-gesteuert? das serial-port-dings hat doch so eine nette 
methode "DataReceived" - die wird immer dann aufgerufen, wenn daten 
empfangen wurden.
während einer übertragung nach einem protokoll (egal ob "standard" oder 
selbst gebastelt) kann natürlich "read" verwendet werden aber zum 
abfragen ob daten angekommen sind, die abgeholt werden müssen ist 
datareceived die bessere lösung (ähnlich rxc-interrupt am avr). wenn 
immer drei bytes übertragen werden, kann natürlich in der 
datareceived-methode auch ein read verwendet werden um den rest zu 
bearbeiten.

achim wrote:
> Wenn ich vom MC zu PC Daten schicke, dann werden die von C# immer als
> ASCII Zeichen interpretiert.
>
> Wenn ich beispielsweile eine 6 schicke, dann kommt eine 54 an.

schickst du 6 oder '6' zum pc?
'6' = 54 bzw. 0x36

von achim (Gast)


Lesenswert?

Ok, danke für den tip mit "DataReceived" !

ich schicke schon die 2, also:

   uint8_t x=2;

.
.
.

   uart_putc(x);

Beim Debugger taucht auch die 2 um Ausgangsregister der UART auf.

von Daniel F. (df311)


Lesenswert?

ein avr ist auch wesentlich weniger wählerisch, wenn es um die 
"darstellung" eines empfangenen bytes in einem textfeld o.ä. geht ;-)

ernsthaft:
wenn du 0x02 schickst, dann kommt im pc-uart auch 0x02 an (außer du hast 
probleme mit der baudrate o.ä.).
nur wird dieses 0x02 abhängig vom verarbeitenden programm als 
steuerzeichen interpretiert (STX, keine darstellung), als irgendein 
symbol auf dem bildschirm dargestellt (terminal-programm) oder evtl. in 
etwas "sinnvolles" umgewandelt ("meinte der sender vielleicht 2?").

ich musste mal für die uni ein programm in c# schreiben, das daten über 
die serielle schnittstelle austauscht. zum einlesen habe ich einfach 
Byte bzw. Byte[] verwendet - damit hatte ich überhaupt keine probleme 
mit irgendwelchen konvertierungen...

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.