www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Welcher Protokoll für RS485


Autor: Sebstian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo   profis,

ich habe eine Frage ,
ich möchte für meine kommunikatin zwischen  einem Master(AVR-µC) d 
mehreren Sensoren(AVR-µC) aufbauen. Ich möchte der Schnittstelle RS485 
benutzen.
Ich habe gelesen, dass dieser Bus  keine definierte Bus-protokoll hat.
Kann  ich dafür zum Beispiel, dann der  Protokoll für I2C(TWI) benutzen, 
oder CAN  oder ...  ????

oder   gibt es was spezifisches für RS485 ??
Denn mir ist esnicht ganz klar wie ich den Transmit und Receives 
funktion implementieren kann. Ich weiß nicht genau wie ich die 
unterchiedlichen Frame innerhalb  eines Formats senden Kann.


Ich würde mich freuen  für konstruktive beiträge.

Sebastian

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo Leute ,

hat jemand eine Idee ??

danke
Sebastian.

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
na, so ungeduldig...
Was hast du denn bis jetzt selbst gesucht/gefunden? Gar nichts?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>hat jemand eine Idee ??

Mit deinen spärlichen Angaben, nicht so richtig.

MfG Spess

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Sebstian (Gast)

>Ich habe gelesen, dass dieser Bus  keine definierte Bus-protokoll hat.

Ist auch so.

>Kann  ich dafür zum Beispiel, dann der  Protokoll für I2C(TWI) benutzen,

Nein.

>oder CAN  oder ...  ????

Nein.

>oder   gibt es was spezifisches für RS485 ??

Meist nutzt man ein logisches RS232, also den UART im uC.

>Denn mir ist esnicht ganz klar wie ich den Transmit und Receives
>funktion implementieren kann.

Wie bei RS232. Wahlweise voll- oder halbduplex. Meist halbduplex. MAX485 
ist dein Freund.

> Ich weiß nicht genau wie ich die
> unterchiedlichen Frame innerhalb  eines Formats senden Kann.

Soweit bist du noch lange nicht. Beschäftige dich erstmal mit EINFACHEN 
Grundlagen. DMX512 ist ein guter Anfang.

MFG
Falk

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok

anders formulliert ,
wie kann  die Kommunikation zwischen ein Master und Slave über den 
RS485- Schnittstell in einem Busanordnung erfolgen.

was ich schon weißbei der RS485 ist, dass der Aufbau eines Frames 
folgendr massen aussieht: Als erstes das Adressbyte mit gesetztem 9. 
Bit, anschließend die Paketlänge, in diesem Fall
8 Byte, danach die 8 Datenbytes und zum Schluß die Schecksumme. Bei 
allen Bytes werden 9 Bit übertragen aber nur bei der Adresse ist dieses 
Bit
gesetzt. Dies führt dazu dass, bei gesetztem 9.Bit jeden Slave erkennt 
der Start einer neuen Übertragung. Erst der Slave dessen Adresse 
enpricht sendet ein ACK zurück (seine Adresse) und die anderen   bleiben 
auf empfang bis eine neuen Datensatz  mit gesetzten 9.bit übertragen 
wird.

Format

1 Adressebyte Paketlänge($8)| datenbyte |  Cheksumme

hier ist ein Auszug der initialisierung.   ATmega32

void RS485_Init (void)
{
     // Baudrate Einstellung
  //UBRR0L = (TAKT/(16UL*BAUD))-1;  //Baudrate
  UBRR0H = (unsigned char) (TEILER>>8);
    UBRR0L = (unsigned char) TEILER;

  //Sender und Empfänger ein
  UCSR0B |= (1<<TXEN0)|(1<<RXEN0)|(1<<UCSZ02);

    // Datenformats: 9 Datenbits, 1 Stoppbit
    UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);

}


wie kann die Übertragung (sende TX und Empfang RX)- Funktionen aussehen, 
damit den gesamten Format übertragen wird .

ich hoffe ich war etwas ausführlicher in der beschreibung
danke

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>DMX512 ist ein guter Anfang.

ich  habe mal gegooglet , aber ich  nichts vergleichbares

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Sebastian (Gast)

>wie kann  die Kommunikation zwischen ein Master und Slave über den
>RS485- Schnittstell in einem Busanordnung erfolgen.

Tausend und eine Möglichkeit.

>was ich schon weißbei der RS485 ist, dass der Aufbau eines Frames
>folgendr massen aussieht:

Falsch. RS485 definiert nur elektrische Sachen, keine Logik.

> Als erstes das Adressbyte mit gesetztem 9.
>Bit, anschließend die Paketlänge, in diesem Fall
>8 Byte, danach die 8 Datenbytes und zum Schluß die Schecksumme.

Ohne S. Du willst nichts bezahlen ;-)

> Bei allen Bytes werden 9 Bit übertragen aber nur bei der Adresse
> ist dieses Bit gesetzt.

Kann man machen, muss aber nicht.

>wie kann die Übertragung (sende TX und Empfang RX)- Funktionen aussehen,
>damit den gesamten Format übertragen wird .

Beschäftige dich erstmal mit RS232 zwischen PC und uC. Wenn du das drauf 
hast, mach dich an RS485.

MFG
Falk

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi  Falk,
 danke für die Anwort.  es bringt mir  zwar nicht zu viel weiter , aber 
deine Hilfe war/ ist Wert.

Seb.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe in einer Anwendung auch RS485 eingesetzt.
Ein Protokoll ist ganz einfach implementiert. Meine Anwendung sendet 
einen String über den RS485-Bus der als erstes die Geräteadresse und 
dann den eigentlichen Befehl enthält.
zB: "B003S100"
- "B003" kennzeichnet jetzt Befehl an Gerät 003
- ist dann Schrittweite 100
Das Gerät antwortet dann mit "OK003 100" das bedeutet Befehl verstanden.
Nach dem OK können entsprechend dem Befehl weitere Daten vom Gerät 
gesendet werden.
Falls keine oder eine falsche Antwort kommt wird nocheinmal gesendet.

Auf der Platine kann ich den 485 Treiber-IC einfach gegen einen 232 
Treiber-IC austauschen und habe somit auch einen RS232-Bus.

Da ich die Geräte über das Hyperterminal-Programm steuere habe ich auch 
in den Datenübertragungsparametern nur ganz einfache Einstellungen:
9600 Baud, 8 Datenbits, keine Parität und 1 Stopbit.

Je nach Gerätetyp (485/232) brauche ich nur einen Konverter an meine 
COM-Schnittstelle zu hängen.

Gruß Micha

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der TE sieht wohl bei 485 was ganz besonders ...

es ist quasi bei 2drahtbetrieb aber nur RS232 im halbduplexbetrieb
die max485 werden zum senden und empfangen umgeschaltet

ruhezustand sind ALLE auf empfang
der master kann somit immer senden

ALLE slaves empfangen das selbe protokoll und entscheiden anhand der 
adresse ob sie gemeint sind .. wenn nicht verwerfen
der slave mit dieser adresse antwotet darauf und alles ist ok

man kann dazu jede belibige uart routine verwenden und erweitet diese 
mit dem  enable pin

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So schwierig is so ein Protokoll nun auch wieder nicht. Ein Packet hat 
ein Startzeichen resp eine Startsequenz, Header genannt. Dieser Header 
muss verschiedene Anforderungen erfuellen. Falls man verschieden lange 
Packete verwenden will, so muss die Laenge teil des headers sein. Falls 
gewuenscht kann man vor dem effektive Stratzeichen noch 
Synchronistationszeichen haben, die helfen dem Empfaenger, falls der mal 
ein Zeichen verloren hat und ausm Tritt ist. Falls man eine sender und 
viele Empfaenger hat, so muss eine Start- und eine Zieladresse, zB als 
Byte, Teil des Headers sein. Falls man die Daten sicher uebertragen 
will, meint, kaputte Daten erkennen will, so macht man einen CRC ueber 
alles und haengt den CRC hinten an die Meldung an. Falls eine Meldunf 
laenger als ein Packet sein kann, so muss man noch ein Sequenznummer 
mitsenden, dass der empfaenger so einzelne bloecke, die kaputt gingen, 
neu anfordern kann. Man kann sich ueberlegen, ob jedes Packet 
beantwortet werden muss. Falls eine Antwort ausbleibt : neu senden - 
aber wie oft ? Standardmaessig verfaehrt man bei einer kaputten 
Nachricht wie bei einer nicht verstandenen Nachricht, gleich wie bei 
einer Nachricht an eine fremde Adresse : keine Antwort geben.
Ein Master -Slave Netzwerk hat einen Master und viele slaves. Der Master 
macht alles, darf senden wann er will. Ein slave darf nur Antwort geben. 
Das muss innerhalb einer gewissen Zeit geschehen. Sonst gibt es einen 
Timeout beim Master, der dann entscheidet was weiter zu geschehen hat.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke schön für die Beiträge,

es wid langsam und langsam klarer.

Aber damit der 9.bit übertragung funktioniert , muss ich sowohl bei der 
salve als auch bei  Master ein AVR benutzen oder ?. weil nur bei den 
kann mann  das 9.bit Modus einstellen , die der Slave auch mit 
konfiguriert werden kann.
Weil momentan ich ein Atmega als Master und ein Cypress als slave .

thks.
Seb

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es muss noch klarer werden bevor du anfangen kannst ...

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Der Multi-Prozessor-Mode (mit 9.Bit) hat natürlich gewisse Vorteile. Vor 
allem werden nicht adressierte Slave weniger belästigt. Aber das ganze 
funktioniert auch im 8-Bit-Mode. Nur mit etwas mehr Programmierarbeit.

MfG Spess

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Micha(Gast)
>ich habe in einer Anwendung auch RS485 eingesetzt.
>Ein Protokoll ist ganz einfach implementiert. Meine Anwendung sendet
>einen String über den RS485-Bus der als erstes die Geräteadresse und
>dann den eigentlichen Befehl enthält.
>zB: "B003S100"
>- "B003" kennzeichnet jetzt Befehl an Gerät 003
>- ist dann Schrittweite 100

=> Pollin bei den Slave nach jeder Sendung einem patakt auf dem Bus.


so ein  einfaches  Protokol  , will ich realisieren.

Wie erfolgt dann die Modulation und demodulation von daten.

ich vermute bei Master   hast du ein Strcat() zum Zusammenfügen von 
Adresse und Befehl zu einem String.

Wie schafst du dann noch diese zu extrahieren  bei den Slave.

(wenn ich zu viel wusste  , hätte ch auch nicht gefragt.  ich bin neu in 
der Materie)

danke
Sebastian

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Sebastian (Gast)

>=> Pollin bei den Slave nach jeder Sendung einem patakt auf dem Bus.

Der Ramschladen hat damit wenig zu tun ;-)

>so ein  einfaches  Protokol  , will ich realisieren.

Dann fang mal EINFACH an. PC und uC. ASCII basierend. Ist langsamer, 
kann man aber einfacher debuggen, nämlich per Trminalprogramm.

>Wie erfolgt dann die Modulation und demodulation von daten.

Da wird nix demoduliert, bestenfalls dekodiert.

>ich vermute bei Master   hast du ein Strcat() zum Zusammenfügen von
>Adresse und Befehl zu einem String.

Kann man auch mit printf machen.

>(wenn ich zu viel wusste  , hätte ch auch nicht gefragt.  ich bin neu in
>der Materie)

Fang klein an.

MFG
Falk

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke falk
ichdachte mir  es wäre da das kleinste Niveau.  Ich würde gern der 
Hyperterminal benutzen, aber leider ich bin ein Vista benutzer. Meine 
ansicht und Kenntnisse nach , gibt es sowas nicht bei Vista.
hat jemandd eine alternative .

danke

Autor: Nop M. (gtf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Google Begriffe:
1)Vista 2)Hyperterminal 3) download
bzw.
1)Vista 2)Hyperterminal 4) Alterative

Diese Begriffe sollten doch schon reichen, um so einige sinnvolle 
Ergebnisse
zu erzielen.

Hat's bei Vista etwa keinen WinXP Modus?

http://www.windowsvistaplace.com/hyperterminal-alt...

Gruß
gtf

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und sonst kann man sich mit ein paar Komponenten zur seriellen 
Schnittstelle ein Terminal zusammenkloppen.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo  leute
ich habe mir eine Transmit funktion geschrieben.  aber es funktioniert 
nicht wie erwünscht.

der UDREO bit bleibt für das Senden von Adresse und Data high .
danach geht es wieder auf O und die summe kann dann nicht übertragen 
werden / geht verloren. das programm bleibt an der stelle hängen , da 
UDRE0  nicht gesetzt ist.

warum ist es so ?  ich habe schon alles mögliche probiert.
ich kapiere dass nicht.

Hier  der Transmitfunkt.

void MS_Transmit(unsigned char addresse, unsigned char data,unsigned 
char Summe)
{
     PORTB |= (1 << DDB0);                       //Max485 auf Senden
  Summe=0;

     while ( !(UCSR0A & (1<<UDRE0)));             //Warten, bis UDR leer 
ist für Senden
     UDR0 = addresse;                             //Adresse senden

     while ( !(UCSR0A & (1<<UDRE0)));             //Warten bis UDR leer 
ist für Senden
  UDR0 =data;                 // daten senden

  //berechnung der Cheksumme= data xor addresse
  //Summe=data ^ addresse;
  UCSR0A |= (1<<UDRE0);
    while ( !(UCSR0A & (1<<UDRE0)));            //Warten bis UDR leer 
ist für Senden
    UDR0 =Summe;                  // checksumme senden
   _delay_ms(20);                                //MAX485-Buffer leeren 
lassen

   PORTB &= ~(1 <<DDB0);                        //Max485 auf Emfang



}


Danke

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>_delay_ms(20);                                //MAX485-Buffer leeren

Guck dir mal das TXC-Flag an.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens   es bleibt icht hängen. ich habe es noch debuggen können. Es 
braucht nur ziemlich eine Weile um weiter zu machen. Bestimmt dammit der 
UDRO-puffer leer wird.
danach  geht  UDRE0  wieder auf 1  und TXCO  auf 1.  => Transmit 
completet.
danach geht er weiter mit der Summe(schecksumme) und TXC= wird nicht 
mehr auf 1 gesetzt.


nach  senden  von adresse und  data  ist TXCO weiterhin null. Erst wenn 
UDRE0 wieder auf  1 ist (Puffer empty)   wird dann TXC0  auch auf 1 
gesetzt.
Ich dachte  nach jeder  Übergabe  von Daten an UDR0   wird TXC0 auf 1 
gesetzt.
Scheint aber nicht der fall zu sein.

Was  mache ich dann hier fall. Ich sehe es nicht.


start 8bit 1 stop bit

Danke um Rat

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich dachte  nach jeder  Übergabe  von Daten an UDR0   wird TXC0 auf 1
>gesetzt.

Um es in den Worten meiner Latein-Lehrerin zu sagen: Denken ist manchmal 
Glücksache!

Das TXC-Flag wird gesetzt, wenn der UDR-Puffer (i.d.R. zweistufig) 
komplett leer ist, nicht wenn noch ein weiteres Byte drin steht.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und delays sind manchmal tötlich

gerade 20ms .. is ma verdammt lange wo man andere sahen manchen kann ...
gewöhn dir eine derartige programmierung erst garnicht an

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok
die delay  habe ich raus gemacht.
aber ist zumindest die Senderoutine I.O ?

ich bin dabei die Receive routine zu implementieren

lg
Seb.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Das TXC-Flag wird gesetzt, wenn der UDR-Puffer (i.d.R. zweistufig)
>komplett leer ist, nicht wenn noch ein weiteres Byte drin steht.

Es gibt UDR und das Transmitregister.
TXC ist das Flag für das Transmit-Register. Es wird gesetzt wenn die 
Übertragung eines Bytes abgeschlossen ist und kein weiteres in UDR 
bereitliegt. UDRE wird gesetzt, wenn ein Byte von UDR an das 
Transmit-Register übergeben wurde.

MfG Spess

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß es gilt immer der Moto „wenn nichts raus geht, dann kommt 
nichts zurück“

Nun  setze ich mich dran und Programmiere wie ich es sein kann  und 
bitte bei denen, die mehr Erfahrung in der Sache haben  auf 
Plausibilität zu prüfen.
Ich kann momentan nicht echtzeit an dem Bus testen. Da ich noch keine 
Hardware dafür habe.

Hier ist der receiver routine

unsigned char USART_Receive( void )   // Unterfuntion
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) );
/* Get and return received data from buffer */
return UDR0;
}

 unsigned char MS_Receive( void )    // Receivefuntion des Masters.
{

  for (unsigned int i=0; i<3;i++)      // Buffer initialisieren
  {
    Buffer[i]=0;
  }
  /* Get received data from buffer */
  Buffer[0]=USART_Receive();
  Buffer[1]=USART_Receive();
  Buffer[2]=USART_Receive();
  if( (Buffer[0]!=addresse)| (Buffer[1]= =NACKNWOLEGE))  // zurücksenden 
falls nicht erfolgreich
  {
    MS_Transmit(addresse, data, Summe);
  }
  else
  {
    return 1;
  }
}

Was  ich mache:
 Ich initialisiere zuerst den gesamten Buffer mit Nullen

Nach jedem empfang speichere ich dann mit einem Buffer  wie die Paketen 
angeordnet sind.
0= adresse
1= data
2= summe

Dann vergleiche ich  ob die gesendete Adresse mit der Receiveradresse 
nicht übereinstimmen  oder ob ich ein NACK bekommen habe.  Wenn ja dann 
sende ich erneut.
Wenn aber erfolgreich liefert die Funktion eine TRUE.


Die Transmitroutine dafür ist oben von mir schon gepostet worden.

Danke für anregungen.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
siind die Routine so in Ordnung?

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hätte  ich nach code gefragt;   würde ich hier alle mögliche Sprüche 
bekommen.

nun  schreibe ich den Programm und bitte um rat  da bekomme ich nichts.

Die Hoffnung stirb als letzte.

ich warte noch.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und hoffe dass jemand einen gute idee hat

danke
Sebastian

Autor: Olaf Dreyer (Firma: O.D.I.S.) (dreyero)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sebastian,

ich finde gut dass Du das tatsächlich selber programmieren willst.
Ich habe leider keine Zeit das Programm für Dich zu debuggen.

Geh mal so vor: leihe Dir von einem Bekannten  der Schule  der Arbeit 
/ wo auch immer, ein Speicheroszilloskop oder einen Logicanalyser.
Auf dieser Webseite findest Du auch Artikel und Links zu günstigen 
Logicanalysern. Untersuche Senden und Empfangen erstmal getrennt.
Das senden mit Deiner Schaltung und auf dem Bus mit dem LA messen.
Erst wenn da die gewünschten Bits rauspurzeln mit der Empfangsseite 
weitermachen.

Gruß

Olaf

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Receiver darf nicht blockieren. Den Receiver macht man 
sinnvollerweise mit einem interrupt.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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