www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega8 multiprozessorkommunikation problem


Autor: duron005 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich bin gerade dabein Multikontorllersystem mit 2 atmega8 aufzubauen 
(später werden noch mehrere ATmega8 verbaut)

Der Sender wid folgendermassen initialisiert: (Master)
void USART_Init( unsigned int ubrr)
{
  // Set baud rate 
  UBRRH = (unsigned char)(ubrr>>8);
  UBRRL = (unsigned char)ubrr;
  // Enable receiver and transmitter--> 9 bit modus einstellen durch register bit UCSZ2 
  UCSRB = (1<<TXEN) | (1<<UCSZ2);// | (1 << RXCIE) |(1<<RXEN);  
  // Set frame format: 9data, 1stop bit 
  UCSRC = (1<<URSEL)|(0<<USBS) | (1<<UCSZ0)| (1<<UCSZ1);
}

Die Senderoutine sieht so aus (Master):
void USART_Transmit( unsigned char data, unsigned char adress)
{

  /* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) )
  ;
  UCSRB =UCSRB & 0b11111110;    //bit zuerst loeschen
  UCSRB =UCSRB | adress;      //dann das 9te bit setzen


  /*daten senden*/
  UDR = data;
}



Die Daten werden in der interruptservice routine ausgelesen und zwar 
folgendermassen (Slave):
SIGNAL(SIG_UART_RECV)
{


  if(UCSRB&0b00000010) //wenn 9tes datenbit existiert
  {
    UCSRB=UCSRB&0b11111101;    //9tes bit loeschen
    mydata=UDR;
    
 
    UCSRA=UCSRA|0b00000001;                       //multiprozessormodus aktivieren
    
    if  ( (KONTROLLERADRESSE==mydata)//checke ob ich damit gemeint bin
    {
    
      UCSRA=UCSRA&0b11111110;               //multiprozessormodus aktivieren
      
      return;            // aus funktion zurueckgehen
    
    }
    else
    {
      return;
    }
  
  }

  mydata=UDR;

}  



Initialsierung  der RS232 im Slave:
void USART_Init( unsigned int ubrr)
{
  // Set baud rate 
  UBRRH = (unsigned char)(ubrr>>8);
  UBRRL = (unsigned char)ubrr;
  // Enable receiver and transmitter--> 9 bit modus einstellen durch register bit UCSZ2 
  UCSRB = (1<<RXEN) | (1<<UCSZ2)| (1 << RXCIE);//|(1<<TXEN);
  // Set frame format: 9data, 1stop bit 
  UCSRC = (1<<URSEL)|(0<<USBS) | (1<<UCSZ0)| (1<<UCSZ1);
  UCSRA =UCSRA|0b00000001;        //multipozessor kommunikation aktivieren // es wird wieder auf die naechste adresse gewartet
}

Das ganze sollte so funktionieren:
Der Master schickt ein Adressframe. Der Slave erkennt ob das Adressframe 
für ihn bestimmt ist. Wenn ja loescht er das MPCM bit (damit werden auch 
Dataframes akzeptiert). Der Slave akzeptiert nun alle Dataframe bis 
wieder ein Adresframe erkannt wird ( 9tes bit gesetzt) Das ganze 
funtioniert auch soweit. Ich schicke zum Beispiel einmalig ein 
Adressframe. Danach schicke ich nur noch Dataframes und sporadisch 
erkennt der Slave meine Dataframes nicht mehr als Dataframes. Nur durch 
erneutes senden der Adresse werden die Dataframes wieder akzeptiert. 
Sieht jemand einen Fehler in meinem Code?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
__interrupt  void rx_int()
{
char temp, mpcm;
  mpcm = UCSRB & 2;    // adresse oder datum
  temp = UDR;    /* zeichen immer lesen */
  if(mpcm) {
    if(temp == my_address) {  // adressierung
      UCSRA = 0;    /* MPCM-bit abschalten */
      ser_status |= (ADRESSIERT + NEUE_ADRESSE);
      clr_inbuf1();    // synchronisieren
      clr_outbuf1();    // nichts mehr ausgeben
    } else {
      UCSRA = 1;    /* MPCM-bit einschalten */
      ser_status &= ~ADRESSIERT;
    }
    return;
....

So mache ich es beim Empfangen; vergleiche bitte selbst.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
duron005 wrote:
> Hallo,
>
> Ich bin gerade dabein Multikontorllersystem mit 2 atmega8 aufzubauen
> (später werden noch mehrere ATmega8 verbaut)

Wie darf ich mir das vorstellen? Da eignet sich RS232 nicht zu, es sei 
denn Du benutzt RS485? Hier wuerde ich zum Bleistift TWI anbieten.

Sind die Prozessoren auf dem selben Board oder wie gross ist die 
Distanz? Beschreibe erstmal, was Du machen willst, bevor Du nach einer 
Loesung fragst.

Michael

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>UCSRA=UCSRA|0b00000001

Gut, wenn man die Funktion des niedrigstwertigen Bits in UCSRA im Kopf 
hat (ich muss da gerade leider passen).  Sonst weiß man gar nicht, was 
diese Zeile bewirkt, und müsste zur Klärung der Frage das Datenblatt 
herauskramen.

Tipp: Jedem belegten Bit in den I/O-Registern ist ein Namenskürzel 
zugewiesen, und wenn man es benutzt, macht das den Quellcode nicht 
unverständlicher.  Hat auch für einen selbst Vorteile, spätestens dann, 
wenn man nach nem halben Jahr noch was an dem Code ändern will.

Na, erinnerst Du Dich an 
Beitrag "atmega8 multiprozessor kommunikation rs232"

>"Nein, sowas läuft zum
>Beispiel ein paar Minuten und stürzt dann "völlig unerklärlicherweise"
>ab.  Da kann man bei der Fehlersuche dann viel Spaß haben."

Fast schon prophetisch, was? ;-)

Autor: duron005 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Die Distanzen sind mindestens 25 meter. TWI eignet sich daher leider 
nicht dafür.
Der Grund wieso ich die rs232 Schnittstelle nehmen möchte ist, dass ich 
weniger Bauteile benötige. Ich denke schon dass ich ein einfaches System 
damit aufbauen kann, wenn immer nur Master an einen Slave Daten schickt, 
und dieser dann antwortet. Slaves sollen niemals miteinander reden 
dürfen.

lg

Autor: duron005 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe deine routine gerade getestet. Hat manchmal funktioniert  und 
manchmal nicht (wie meine routine)
Das einzige was unterschiedlich ist sind die Funktionsaufrufe
      clr_inbuf1();    // synchronisieren
      clr_outbuf1();    // nichts mehr ausgeben

Diese habe ich nicht eingebunden, weil ich den Codeinhalt nicht kenne. 
Kannst du mir den Code dieser routinen reinstellen, dass ich es mit 
diesen noch versuchen kann?

danke und lg

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joa aber an ner RS232 kannst Du nur insg. zwei Controller anschliessen. 
Und bei 25 Metern duerften auch nur kleine Baudraten moeglich sein. Kenn 
jetzt die Spec nicht genau aber das ist schon ne ziemlich lange Strecke.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Diese habe ich nicht eingebunden, weil ich den Codeinhalt nicht kenne.

Die brauchst Du nicht.
Welche Frequenz ist eigentlich auf Deinen Quarzen aufgedruckt?

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael G. wrote:
> Joa aber an ner RS232 kannst Du nur insg. zwei Controller anschliessen.

Nööö...
Es gibt verschiedene Möglichkeiten, mehrere Controller über RS232 
miteinander zu verbinden.

Man kann durch Protokoll dafür sorgen, dass die TX aller nicht 
adressierten Slaves deaktiviert und hochohmig sind, worauf sie parallel 
geschaltet werden können.

Man mann die TX aller beteiligten Controller über Puffer mit Open-Coll 
führen, das gibt zusätzliche Sicherheit gegen Schäden bei Kollisionen, 
erlaubt Kurzschlussschutz und erhöht etwas die Reichweite.

> Und bei 25 Metern duerften auch nur kleine Baudraten moeglich sein.

Kleine Controller mit kleinen RAMs (Mega8) brauchen wohl selten hohe 
Bausraten, wenn sie Informationen austauschen wollen. Es ist halt kein 
Multimedia.

> Kenn
> jetzt die Spec nicht genau aber das ist schon ne ziemlich lange Strecke.

Sicher ist RS485 besser geeignet, erfordert aber auch einen höheren 
Aufwand. Und der ist nicht in jedem Falle gerechtfertigt.

...

Autor: duron005 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
3.6864 MHZ.. Baudrate habe ich ganz gering eingestellt.. 9600 baud. An 
Übertragungsfehler glaube ich kaum,weil wenn ich zuerst die Adresse 
schicke und dann erst die Daten, es auch immer funktioniert.

Die Höhe der Baudrate ist mit ganz egal. Kann so klein wie möglich sein, 
da es nicht viele Daten sind. Wichtig ist mir nur, dass es richtig 
ankommt, auch wenn ich es 5 mal schicken muss. Zeitkritisch ist es auch 
nicht. Wie gesagt möchte ich das Softwwartechnisch lösen, damit immer 
nur einer sendet, und dieser nur mit dem Master kommuniziert. Die Slaves 
müssen keine Daten miteinander austauschen. rs484 kommt nicht in Frage 
da ich einen erhöhten bauteil aufwand habe und eine zusätzliche 
Datenleitung brauche. 25 meter 3 adriges Kabel habe ich schon und möchte 
mir nicht ein neues kaufen. Außerdem sind 4adrige Kabel teurer als 3 
adrige.

lg

Autor: Alter Mann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es als Alternative mit einer Ringleitung? Also

TxD Controller 1 an RxD Controller 2
TxD Controller 2 an RxD Controller 3
TxD Controller 3 an RxD Controller 4
TxD Controller 4 an RxD Controller 5
TxD Controller 5 an RxD Controller 6
TxD Controller 6 an RxD Controller 1

Man muss dann nur über die Programmierung sicherstellen, das die Daten, 
die  nicht für den jeweiligen Controller gedacht sind immer weiter 
gereicht werden.

Das vermeidet es, einen Kollisionsschutz einbauen zu müssen. Jeder 
Controller kann senden, wann er will, er muss nur nachher die 
empfangenen Datenpakete weiter reichen, die nicht für ihn bestimmt sind.

Der Nachteil ist natürlich, das, wenn ein Controller ausfällt oder die 
Leitung an einer Stelle defekt ist, das ganze System stillgelegt ist.

Florian

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Alter Mann (Gast)

>Wie wäre es als Alternative mit einer Ringleitung? Also

Ist nicht sonderlich schön, weil

>Der Nachteil ist natürlich, das, wenn ein Controller ausfällt oder die
>Leitung an einer Stelle defekt ist, das ganze System stillgelegt ist.

Strangförmiger Bus ist scon OK, und wenn nur ein Master die Slaves 
abfragt, geht das schon.

MfG
Falk

Autor: duron005 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ringpuffer kommt nicht in Frage, weil nicht immer jeder kontroller 
vorhanden sein muss;)

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.