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
na, so ungeduldig... Was hast du denn bis jetzt selbst gesucht/gefunden? Gar nichts?
Hi
>hat jemand eine Idee ??
Mit deinen spärlichen Angaben, nicht so richtig.
MfG Spess
@ 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
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
>DMX512 ist ein guter Anfang.
ich habe mal gegooglet , aber ich nichts vergleichbares
@ 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
hi Falk, danke für die Anwort. es bringt mir zwar nicht zu viel weiter , aber deine Hilfe war/ ist Wert. Seb.
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
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
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.
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
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
@ 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
@ 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
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
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-alternative-in-windows-vista/downloads/de/ Gruß gtf
Und sonst kann man sich mit ein paar Komponenten zur seriellen Schnittstelle ein Terminal zusammenkloppen.
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
>_delay_ms(20); //MAX485-Buffer leeren
Guck dir mal das TXC-Flag an.
Ü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
>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.
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
ok die delay habe ich raus gemacht. aber ist zumindest die Senderoutine I.O ? ich bin dabei die Receive routine zu implementieren lg Seb.
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
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.
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.
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
Der Receiver darf nicht blockieren. Den Receiver macht man sinnvollerweise mit einem interrupt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.