PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : verlustfreie Datenübertragung(rs232)



PasstScho
12.03.2005, 17:54
Hi,
Ich habe einen µC, der mit 19200 oder schneller über die serielle Schnittstelle empfangen soll.
Meistens geht das auch, aber irgendwie gibt es manchmal Probleme, da, glaube ich, Bytes verloren gehen.
Ich schätze, dass es an der zu schnellen Übertragung liegt.
Ich benutze beide Timer, in denen relativ viel Code steht.
Kann es sein, das der µC ein Byte überspringt, wenn gerade ein byte ankommt, während ein zeitaufwändiger Timer-Interrupt ausgeführt wird, und der UART Interrupt zu lange warten muss?
Kann ich einfach noch den CTS Pin vom PC an den Max232 anschließen, um dann immer, wenn ein Timer ausgeführt wird, dem PC zu sagen, dass er warten soll, und am Ende des Interrupt, dass er weiter Senden darf?
Sollte das mein Problem beheben, und wie muss ich dann die anderen Pins der seriellen Schnittstelle verbinden(Bisher nutze ich nur rxd und txd. Pin 4,6,8 sind miteinander verbunden)?
Viele viele Fragen ... hoffentlich auch Antworten...

MfG Alex

PicNick
12.03.2005, 18:00
Hi, ich würde die XON/XOFF Methode empfehlen, überhaupt, wenn der PC-Partner ein Terminal ist (die können das). Natürlich geht auch HW-Handshake, aber das braucht Drähte.
Ich will schon hoffen, daß du ein kleines Bufferlein beim Empänger hast, und nicht einzeln die Bytes sofort verarbeiten mußt.

slm
16.03.2005, 00:45
Hi Alex,

-Wie lange ist dein Kabel?
->Wenn sehr lang (über 20meter neben Stromleitungen) solltest Du über eine Abschirmung nachdenken.
-Wer gibt den Takt an?
Gemeint ist der Timer der fuer die UART zuständig ist.
Je nach der Quarzfrequenz der Clock, muss der Timer genau abgestimmt werden.
Manchmal liegt der Timerwert genau auf einer Theoritische Kommazahl, was eine Zeitverschiebung und somit ein "ab und zu" verlust eines Bytes oder Bits zu folge hat.
Ich wuerde dann eine anderen Quarz nehmen bsp: 11.0592 Mhz
- Wie lange ist deine Interuptservice routine?
Sie sollte nur den Byte vom register nehme und gebenenfalls in einen Puffer legen.
Dauert es zu lange wird das nächste Byte im register vom übernächsten ueberschrieben.
- Welche priorität hat der Interrupt?
Kann es sein das ein anderer interrupt ihn davon abhält den Byte zu nehmen

Meine ISR die hervorragend klapt (fuer mcs51)

void serInterruptHandler(void) interrupt SI0_VECTOR// using 1 // interrupt Nr.4
{
if (RI==ON) // read flag
{
RI=OFF; // reset flag
if (Rsize<BUFSIZE_R) // when buffer is not full
{
RBuf[Rindex]=SBUF; // save caracter in the buffer
Rsize++;
Rindex++;
if (Rindex>=BUFSIZE_R) Rindex=0; // at the end of the buffer
}
}
if (TI==ON) // transmit flag
{
TXTBLOCK=OFF;
TI=OFF; // reset flag
}
}

PasstScho
17.03.2005, 17:21
Hi,
Ja, ich habe einen 16Mhz Quarz, wo eine krumme Zahl rauskommt. Es ist einfach nicht möglich mit dem Quarz eine geeignete Geschwindigkeit zu finden. Aber wirkt sich das so gravierend aus(so krumm ist es dann doch nicht)? Die Interruptroutine ist einfach zu lang. Ich glaub ich werde deine da mal einbauen, dann könnte sich das erledigt haben.
Danke für die Hilfe, MfG Alex

17.03.2005, 20:05
Übrigends in manchen controller Datasheet, geben die Hersteller die optimale timer Werte für die verschiedenen Baudraten und Quarze.
Noch ein typ, wenn du in c programmierst dann gehe mal auf http://sdcc.sourceforge.net/.
Dort gibt es ein tollen open source compiler umsonst.
Den benutzte ich.
Wenn du das package herunterläds hat du auch den Quellcode für die Library.
Eine ware Fundgrube.
Dort habe ich meine interruptroutine "geklaut" .

Mfg Stephan