Forum: Mikrocontroller und Digitale Elektronik USART-RS232-PC( Protokol oder Umbau von STK500 ?)


von Alexander N. (koljan)


Lesenswert?

Guten Tag, allerseits,
Folgende Problem steht vor mir...
Ich muss eine verbesserte zuverlässige Kommunikation zweier Systeme
entwickeln,
1.Fall:
mikrocontroller sendet ununterbrochen die auswertbare Daten an RS232
des STK500 -> PC empfängt die nur, aber muss imstande sein,die
Anwenderbefehle zu senden, so dass der Controller die auch bekommt.
Meine Frage ist wie erkennt stk500, dass die neue Daten vorhanden sind,
während der Übermittlung? PC-Daten werden vermisst!
Da die STK500 verfügt über RS232-Spare aber nur mit RXD,TXD (keine
RTS,DTR,RI,CTS) Leitungen und die einfach blockiert sind wenn
Controller sendet! Und wenn ich die Interruptausführung aufhalte, um
nach neuem Input zu sehen, wird es nicht zum Überfühlen des Puffers
kommen?
Entweder muss ich die RS232 (inklusiv MAX202 ) neu konzepieren, oder
die Hoffnung haben, dass das Überschreiten des Puffers nicht auftritt.

2.Fall:
PC sendet ständig die Daten zum Nacharbeiten an STK500,dann möchte
Controller was senden, werden es nach dem Auslösen des Interrupts die
vom PC gesendete Daten verloren gehen?!
was könnte man entwickeln, was die ganze Kommunikation zwischen PC und
STK500 steuern kann( mit Fehlermeldungen und Aufhaltungen der
Interrupts). Was benutzt man besser Polling oder Interrupt?
Ich weiss einfach nicht wie ich anfange.
Habt Ihr vielleicht wertvolle Tips für mich, wie ich das Problem
angehe?


Danke im voraus,
(danke-für eure Zeit und Wissen :~)) mfg Alex )

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>Was benutzt man besser Polling oder Interrupt?
Interrupt mit einem Puffer - für beide Richtungen.
Ich gehe davon aus, dass du mit STK500 den Controller meinst, der auf
das STK500 gesteckt wird; nicht die Programmier-Controller.

Zum Senden und Empfangen solltest du auf jeden Fall eine Kommunikation
mit Interrupts aufbauen, die die Daten in einen Puffer schreiben
(Empfang) und aus einem Puffer lesen (Senden).
In der Empfangs-Interruptroutine setzt du dann ein Flag, das der
Hauptschleife anzeigt, dass neue DAten empfangen wurden.
Die Puffer mußt du natürlich so groß auslegen, dass es zu keinem
Überlauf kommen kann. Die Grösse hängt also von der Baudrate, der
Datenmenge und der Verarbeitungsgeschwindigkeit dieser Daten ab.

von crazy horse (Gast)


Lesenswert?

steuern kannst du das ganze mit XON/XOFF (Softwarehandshake), ist
normalerweise aber nicht erforderlich. Jedes einzelne Byte braucht rel.
viel Zeit zur Übertragung und belastet den Prozessor im Interruptbetrieb
kaum. Bei 9600 Baud beispielsweise tröpfelt etwa jede ms ein Byte
herein, und du hast bei 16MHz 16.000 Takte, um das zu verarbeiten.
Interruptaufruf, Byte abholen und im Buffer zwischen dauert vielleicht
50 Takte, also nur einen sehr kleinen Teil der zur Verfügung stehenden
Zeit.

von Alexander N. (koljan)


Lesenswert?

Danke Rahul,
Ich arbeite mit Atmega8515 und in seine Architektur(Datenblatt) hat er
UDR und Shift Register, die sich in USART befinden.
Ich muss also zusätzliche Puffern schaffen wo ich die ankommmende Bytes
kopiere, aber wenn die UDR und Shift Register voll sind, besteht keine
Möglichkeit die Daten zu empfangen/senden?
PC merkt das nicht und sendet weiter, infolge dessen gehen die Daten
verloren.
Wenn das vollständige RS232 wäre, hätte ich das Problemm nicht mehr, da
ich anhang der Signale die Interrupts ausführen könnte.

von Wolfram (Gast)


Lesenswert?

Hast du das Datenblatt schonmal durchgelesen?
Wenn du ein zeichen empfängst kann auch ein Interrupt ausgeloest
werden
und dort kannst du dafuer sorgen das das Zeichen in einen groesseren
Puffer im RAM kommt.

von Alexander N. (koljan)


Lesenswert?

Danke crazy horse,
ich benötige ein zusätzlichen Signal, um neue Daten zu identifizieren,
da Receive und Transmiter benutzen gleiche UDR und
Shiftregister,dadurch
wird es nicht gewährleistet dass ich gleizeitig senden/empfangen kann.
ich kann die Sendephase des Controllers unterbrechen,weil ich dafür
gleichen Register(Flags) benötige

von Alexander N. (koljan)


Lesenswert?

An Wolfram,danke,
o.k.
Aber wie kann ich interrupt mit einem neuen interrupt unterbrechen?
Da zum Senden auch ein Interrupt benutzt wird?

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>Wenn das vollständige RS232 wäre, hätte ich das Problemm nicht mehr,
>da ich anhang der Signale die Interrupts ausführen könnte.

Der AVR hat eine vollständige serielle Schnittstelle.
Sobald der Controller ein Byte empfangen hat, löst er ein Interrupt
aus, das Hauptprogramm wird unterbrochen und die
Interrupt-Service-Routine (ISR) wird aufgerufen.
In dieser Routine liest man das UDR aus und sichert es in einer
Variablen. Diese Variable kann teil eines Arrays sein.
Es wird noch ein Flag gesetzt, das dem Hauptprogramm signalilsiert,
dass neue Daten eingetroffen sind.
Ist die ISR zuende, macht der Controller an der Stelle weiter, wo das
Hauptprogramm unterbrochen wurde.
Dieses Hauptprogramm durchläuft dauernd eine Abfrage, ob das Flag
gesetzt ist, und reagiert entsprechend darauf.
Sooo schwer ist das nicht!

von Alexander N. (koljan)


Lesenswert?

Jungs,vielen Dank an alle Beteiligten,
aber ich versuche die Situation zu beschreiben, wo gleichzeitig oder
mit ganz minimalen Verluste kommunitiert wird. Oder durch eine Meldung
der Datenfluss umgeleitet/aufgehaltet wird

von Peter D. (peda)


Lesenswert?

Die Handshake-Signale kannst Du voll vergessen.

Das sind nur zusätzliche IO-Pins, die UART kümmert sich keine Deut
darum.


Was Du brauchst, ist ein Protokoll, z.B. ein Ping-Pong Protokoll:

Jede Station weiß, wie groß der Puffer der Gegenseite ist und sendet
dann Blöcke, die max so groß sind und wartet dann auf ein Signal, daß
sie den nächsten Block senden darf.

Z.B. haben ich in meinem ATmega8 512 Byte Puffer eingerichtet, d.h. der
PC darf maximal 512 Byte am Stück senden und muß dann auf Antwort
warten.

Um nun zu prüfen, ob ein Block gültig ist, hängt man z.B. noch ne 16Bit
CRC mit ran.


Peter

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>um neue Daten zu identifizieren, da Receive und Transmiter benutzen
>gleiche UDR und Shiftregister

Die heissen vielleicht gleich. Es sind aber 2 unterschiedliche
Register, die unter der gleichen Adresse angesprochen werden.
Wenn man versucht, das Sende-UDR auszulesen, bekommt man den Inhalt des
Empfangs-UDR geliefert.

von Alexander N. (koljan)


Lesenswert?

An inoffizieller WM-Rahul,
Nein eben nicht die hat nur 2Leitungen RX TX.Die anderen sind gekreuzt
oder auf Masse gelegt(Schaltplan),dadurch werden nicht alle
Möglichkeiten der RS232 erschöpft.


Ich werde dankend eure Antworten entgegenehmen(VIELEN DANK) ich muss
nur kurz weg(ca.20min)
sorry,sorry,sorry,
 bis dann

MFG Alex

von Peter D. (peda)


Lesenswert?

"...Receive und Transmiter benutzen gleiche UDR und
Shiftregister,dadurch wird es nicht gewährleistet dass ich gleizeitig
senden/empfangen kann."


Quatsch mit Soße.

Du hast nicht ins Datenblatt geschaut.
Der Name UDR ist zwar gleich, aber schreiben und lesen gehen auf 2
verschiedene Register !

Die UART ist daher sehr wohl Voll-Duplex fähig.


Peter

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>Nein eben nicht die hat nur 2Leitungen RX TX.Die anderen sind >gekreuzt
oder auf Masse gelegt(Schaltplan),dadurch werden nicht alle
>Möglichkeiten der RS232 erschöpft.

Ja, und?
Wie Peter schon schrieb: Die restlichen Leitungen sind irrelevant.
Dein Puffer muß nur die entsprechende Grösse haben.
Die brauchst du bei 16MHz aber eigentlich auch erst dann, wenn du auf
einen Schlag mehr als 2 Bytes verarbeitest (z.B. Strings).
Wenn du wirklich ein Hardware-Handshake bauen willst/mußt, dann kannst
du Portpins und einen weiteren MAX202 (oder einen MAX232 o.ä.) nehmen.
Um das Handshake musst du dich aber dann selber kümmern.
Soweit ich weiß, kümmern sich andere (externe) UART auch nicht um die
Handshake-Leitungen. Das sind nur irgendwelche Pins, die auf das Ändern
von Registern im Chip reagieren. Die Engangspins auf RS232-Seite könnten
vielleicht noch einen Interrupt auslösen. Den muß der Host-Controller
aber auch auswerten.

Vielleicht erzählst du mal was zu den Randbedingungen:
Wieviel Daten bei welcher Baudrate und wie schnell müssen die
verarbeitet werden?
Was soll der Controller überhaupt machen?
[OT]
Vielleicht solltest du mal in eine Tüte atmen. Du scheinst mir etwas zu
hyperventilieren.
>ich muss nur kurz weg(ca.20min)
Kacken?
[/OT]

von Wolfram (Gast)


Lesenswert?

Irgendwie siehst du Probleme, wo gar keine sind. Bevor du eine
verbesserte Kommunikation zwischen 2 Systemen entwickelst; hast du
schonmal eine einfache Kommunikation zwischen 2 Systemen entwickelt?
Statt ueber das darüberliegende Protokoll, diskutieren wir hier gerade
über die Funktionalität einer UART.

>Aber wie kann ich interrupt mit einem neuen interrupt unterbrechen?
>Da zum Senden auch ein Interrupt benutzt wird?
???
das ist überhaupt nicht nötig und selbst wenn es passieren würde, ist
das egal, da die jeweiligen Zwischenpuffer unabhängig sein sollten.
Die angesprochenen Zwischenpuffer hast DU zu programmieren.

von Alexander N. (koljan)


Lesenswert?

Cool,danke für Eure Hilfe.

An Peter Dannegger:
>Was Du brauchst, ist ein Protokoll, z.B. ein Ping-Pong Protokoll.
GENAU DAS BRAUCHE ich!
>Die UART ist daher sehr wohl Voll-Duplex fähig
ja jetzt gerufft.
>Um nun zu prüfen, ob ein Block gültig ist, hängt man z.B. noch ne
16Bit
CRC mit ran.
könntest du noch mal erklären, was du meinst.

An inoffizieller WM-Rahul
>Vielleicht erzählst du mal was zu den Randbedingungen
>Vielleicht solltest du mal in eine Tüte atmen.
ja, ich sollte  :)

An Wolfram
>hast du
schonmal eine einfache Kommunikation zwischen 2 Systemen entwickelt?
ja habe ich. Die waren nicht so umfangreich und kompliziert.
Aber eigene Protokoll( Peter's Vorschlag) zu entwickelt, kann ich noch
nicht :((

ich werde mich noch etwas verbessern in Frage USART bevor ich euch mit
meine dumme Fragen belästige...

Anfänger-Mangelhafte Wissen,Geduld und Wille

von Wolfram (Gast)


Lesenswert?

>schonmal eine einfache Kommunikation zwischen 2 Systemen entwickelt?
>ja habe ich. Die waren nicht so umfangreich und kompliziert.
dann verbessere deine einfache Kommunikation auf eine Kommunikation mit
Interrupts und zwischenpuffern, das ist die Grundlage auf der die
Protokollschicht dann aufsetzt. Hier zur Ansicht mal ein Bsp. fuer den
Sendeteil mit Ringpuffer

struct Seriell_Senden
{
char Buffer[Seriell_SendbufferSize];
volatile unsigned char outp;
volatile unsigned char inp;
}Seriell_Senden;

FILE mystdout = FDEV_SETUP_STREAM(uart_putchar,
uart_getchar,_FDEV_SETUP_RW);


ISR(USART_UDRE_vect)
//TransmitInterrupt
{
if (Seriell_Senden.outp!=Seriell_Senden.inp)
  {//Zeichen in Puffer
  Seriell_Senden.outp=(unsigned
char)(Seriell_Senden.outp+1)%Seriell_SendbufferSize;
  UDR=Seriell_Senden.Buffer[Seriell_Senden.outp];
  }
else
  {//Sendeinterrupt aus
  UCSRB&=~(1<<UDRIE);
  }
}

int uart_putchar(char c,FILE *stream)
{
unsigned char tmp;
tmp=((unsigned char)(Seriell_Senden.inp+1)%Seriell_SendbufferSize);
while (tmp==Seriell_Senden.outp){}//solange kein Platz im Puffer warte
Seriell_Senden.Buffer[tmp]=c;
Seriell_Senden.inp=tmp;

//SendeInterrupt auslösen
UCSRB|=(1<<UDRIE);
return(0);
}

von Alexander N. (koljan)


Lesenswert?

An Wolfram:
danke für den Beispiel :)
ich hab riesen Problem, die Struktur des Ping-Pong Protokoll zu
verstehen. Wie genau sollte das  Erlaubnis zum Weitersenden erfolgen?
Oder die Bestätigung über das erfolgreiche Empfangsergebnis aussehen?

Wie könnte es auf code-Ebene aussehen?

von Dirk (Gast)


Lesenswert?

http://www.mikrocontroller.net/forum/read-2-426342.html#new

Hi, indem Beispiel benutzte ich ein FIFO als Empfangsbuffer. Du
koenntest die Daten jetzt sammeln und am Ende auswerten.

Für das Senden kannst du Dir auch ein FIFO bauen und dann per ISR die
Daten vom FIFO aus senden.

Ich hab die Funktionen verbessert und gestern abend mal ein bischen
Ping Pong gesendet und konnte kein Datenverlust feststellen.

Gruß,
Dirk

von Michael U. (Gast)


Lesenswert?

Hallo,

es hindert Dich niemand, einen kompletten Hardware-Handshake
aufzubauen, wenn Du viele Daten in beide Richtungen schicken mußt und
Datenverlust sicher verhindert werden soll. Du brauchst dann 4
Portpins, 2 als Eingang und 2 als Ausgang. Dazu brauchst Du die nötigen
Pegelwandler (ein kompletter 232 z.B.).
Um die Ansteuerung muß Du Dich allerdings komplett in Deiner Software
kümmern...
Aufpassen dabei, wenn Du Stop zum PC schickst, hört der erst auf zu
senden, wenn der interne Buffer des IO-Chips leer ist, da können
durchaus nach dem Stop-Signal einige Byte Daten kommen.
Ob es allerdings einfacher ist, als eine reine Softwarelösung,
bezweifle ich erstmal. Du brauchst einen FIFO zum Senden, einen zum
Empfangen. Senden/Empfangen jeweils in einer Interruptroutine
Byte-weise. Buffer z.B. 128Byte. Wenn Du beim Empfang bei 96Byte bist,
Stop zum PC senden. Wenn Du wieder auf 32Byte bist, dem PC Senden
Empfang wieder erlauben.
Beim Senden genauso: erst schauen, ob der PC empfangen kann, wenn ja,
dann senden, enn nicht, warten.
Wenn man es einmal eingebaut hat, hat es den Vorteil, daß man sich um
den ganzen Kram nicht mehr kümmern muß, nur noch im Hauptprogramm die
Daten aus dem Buffer abholen bzw. den Sendebuffer nachfüllen, wenn
nötig. Das geht aber dann ohne irgendwelche Zeitkritischen
Geschichten.

Gruß aus Berlin
Michael

von Alexander N. (koljan)


Lesenswert?

danke Dirk,
dein code ist sehr hilfsreich, ich werde mir das genau anschauen!
danke Michael für die ausführliche Beschreibung der Vorgehensweise,
aber ich muss erst mal klarmachen, wie es in meinem Protokoll die
Bedingungen aussehen werden,nach welch Kriterien gehandelt wird.

Vielen Dank an alle,
Ihr habt noch ein verzweifelten Anfänger 'gerettet' !!!!
Ich melde mich noch ein mal, als es etwas deutlicher wird
 Mit freundlichen Grüssen,
Alex Nik.

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.