Forum: Mikrocontroller und Digitale Elektronik SPI anfällig für Störungen?


von Yaro (Gast)


Lesenswert?

Hallo Leute,

ich habe in letzter Zeit einige SPI-Busse verwendet, um AVRs 
kommunizieren zu lassen. Manchmal gabs da überhaupt keine Probleme, 
manchmal war der Bus total unstabil, sodass ich einfach nur die Leitung 
etwas knicken musste, und schon traten haufenweise Fehler auf, 
unabhängig von der Sendegeschwindigkeit (immer unter 2MHz). Im Moment 
habe ich auch keine größeren Quellen von elektromagn. Strahlung (z.B. 
Motoren) laufen... nur ein Netzgerät, womit ich alles betreibe.
Mache ich vielleicht was falsch? Was sollte man generell beachten?

Gruß, Yaro

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Manchmal gabs da überhaupt keine Probleme
So kenne ich den SPI auch... ;-)

> Was sollte man generell beachten?
Den richtigen SPI-Modus verwenden.

> sodass ich einfach nur die Leitung etwas knicken musste
Was für eine Leitung?
Wie lang ist die Leitung?
Hast du Serienterminierungswiderstände eingebaut?

von Yaro (Gast)


Lesenswert?

> Den richtigen SPI-Modus verwenden.
Das mache ich... Sonst würde ja überhaupt nix sinvolles übertragen 
werden.

>Was für eine Leitung?
15cm Flachband-Kabel.

>Hast du Serienterminierungswiderstände eingebaut?
Nein, sollte ich das? Wie groß sollen sie bemessen sein?

Gruß, Yaro

von Kay I. (imperator)


Lesenswert?

Flachbandkabel sind der EMV-tot Deiner Schaltung ... da kann sich alles 
mögliche einkoppeln.


Wenn Du da mehrere kHz überträgst, kommst schon in den kritischen 
Bereich. Da kann Abhilfe durch mehrere Mittel geschaffen werden:
- differential pairs (redundante Pegelübertragung und Auswertung der 
Differenz als Nutzsignal siehe RS485)
- 1 Masseleitung parallel zu jeder Signalleitung im Flachbandkabel, 
sodass die Signale immer einen Masse-Bezug "sehen"
- galv. Trennung
- je nach dP/dt (Laständerung über der Zeit) kann es nötig sein, den 
Schaltungsteil hinter dem Flachbandkabel niederohmiger anzubinden, da 
die Ausgleichströme für Spannungsabfall über deinen Versorungsleitungen 
sorgen können. Das kann wiederum zu Fehlinterpretation Deiner 
digital-Pegel führen.

Terminierung
Je nach Bustopologie könntest Deine SPI-Leitungen auch noch terminieren. 
Dazu empfiehlt sich, die Leitungen so auszuprägen, dass überhaupt eine 
richtige Impedanz da ist (Massfläche, Leiterbreite, Leiterabstand zu 
Fläche, ...). Dann kannst beim Leitungstreiber einen Serienwiderstand 
einbauen, um eine Anpassung an die Impedanz zu erreichen. Der Empfänger 
ist hochohmig und sollte daher gegen eine Versorgungsspannung mit einem 
Pullup/Down abgerschlossen sein - jenachdem, welcher der Ruhepegel ist.

Gruß,

Kay

von Falk B. (falk)


Lesenswert?

@  Kay Imperator (imperator)

>Flachbandkabel sind der EMV-tot Deiner Schaltung ... da kann sich alles
>mögliche einkoppeln.

Unsinn. Siehe Wellenwiderstand Ist schon komisch, dass Millionen von 
Festplatten seit Jahrzehnten mit Flachbandkabeln super funktionieren.

MFg
Falk

von Yoschka (Gast)


Lesenswert?

Yaro schrieb:
> unabhängig von der Sendegeschwindigkeit (immer unter 2MHz).


Die Übertragungsrate ist irrelevant !!
Die AVR senden immer mit der gleichen steilen Flanke.
Ab 15cm Leitungslänge wird es hier kritisch.

Bei SPI würde ich die AC Terminierung vorschlagen.
Siehe Wiki.
Flachbandkabel hat es gerne, wenn Du es mit GND, Signal, GND, Signal, 
GND... belegst.

von Andreas F. (aferber)


Lesenswert?

Falk Brunner schrieb:
> Ist schon komisch, dass Millionen von
> Festplatten seit Jahrzehnten mit Flachbandkabeln super funktionieren.

Für die jüngeren, die das vielleicht schon alles nicht mehr kennen 
(;-)): SCSI-3 (Ultra-SCSI) dürfte da im wesentlichen die Spitze dessen 
gewesen sein, wo noch ganz normale Flachbandkabel (ohne die "Tricks" wie 
jede zweite Ader Masse etc.) verwendet wurden. Das waren 20MHz Bustakt 
bei bis zu 3m Kabellänge. Saubere (aktive) Terminierung war da dann 
natürlich Pflicht! Bei SCSI-1/2 (5 MHz bzw. 10 MHz) mit kurzem Kabel 
(<50cm) lief es ggf. auch schonmal ohne Terminierung (sogar im Prinzip 
stabil, man durfte nur nichts am Rechner verändern ;-).

PATA hat es bis UDMA33 mit normalen Flachbandkabeln gebracht, das waren 
dann 8 MHz Bustakt (mit DDR).

Andreas

von Yaro (Gast)


Lesenswert?

Dann werde ich zuerst jede zweite Leitung GND legen, wenns noch 
Störungen gibt, dann Terminierung.
Danke für die schnellen Antworten!

Gruß, Yaro

von Andreas F. (aferber)


Lesenswert?

Yaro schrieb:
> Dann werde ich zuerst jede zweite Leitung GND legen, wenns noch
> Störungen gibt, dann Terminierung.

Nein, umgekehrt. Erstmal um die Terminierung kümmern. GND-Leitungen mit 
der Giesskanne verteilen hilft genau garnicht gegen Signalreflektionen.

Andreas

PS: Naja, vielleicht ein bisschen, wegen erhöhter Kapazität und damit 
Abflachung der Flanken. Trotzdem bleibt's dabei, erstmal Terminierung, 
wenn das nicht reicht, kann man weiterschauen.

von Frankl (Gast)


Lesenswert?

Zu Anfang ca. 25cm Lochraster mit VG Steckern an die Platinen keine 
Probleme.
Jetzt alle Leitungen MOSI MISO SCK SS mit 4k7 an Plus 5V. Jetzt sind sie 
empfindlich bei Induktiven Lasten.

von bensch (Gast)


Lesenswert?

> > Den richtigen SPI-Modus verwenden.
Das mache ich... Sonst würde ja überhaupt nix sinvolles übertragen
werden.

Das würde ich so pauschal nicht behaupten. Je nach Setup- oder Hold-Time 
der Eingänge KANN es auch bei falschen Modus laufen- MUSS aber nicht. 
Wenn dann noch Signalverzerrungen und/oder Laufzeiten dazu kommen, 
geht's halt schief.

von Kay I. (imperator)


Lesenswert?

@ Falk Brunner (falk)
Ich geb Dir schon Recht ... bestehende Platinen funktionieren oft schon 
sehr lange. Auf neuere Platinen kommen jedoch auch neuere Bauteile mit 
steileren Flanken, sie werden in raueren Umgebungen eingesetzt und auf 
vielen alten Platinen sind gar keine uCs  Netzteile  etc. verbaut...
Die EMV-Betrachtung hat durchaus ihre Berechtigung, was man leidvoll 
erkennt, wenn man mal die erste EMV-Optimierung eines Produktes 
durchlebt hat. Man erkennt es auch, wenn das liebevoll erstellte Produkt 
plötzlich bei diesem einen Kunden an dieser einen Stelle in der Anlage 
immer wieder ausfällt.

@  Andreas Ferber (aferber)
Wenn ich mich recht entsinne, gab es da in der Übertragungs-Schicht auch 
großzügige Hemmingdistanzen und selbstheilende Datenkodierung mit 
reichlich Redundanz ;)

@  Yaro (Gast)
wie Andreas Ferber (aferber) schon schreibt ... versuch mal die 
Impedanzanpassung. Du könntest es zunächst mit 100R bei den 
Treiber-Ausgängen versuchen. Das ist mal ein Versuchswert - vielleicht 
ist er bei Dir auch höher.

Sender                                           Empfaenger
-------+                                         +--------+
       |                                         |        |
       O--100R-----------Leitung----------+------O        |
       |                                  |      |        |
---O---+                              C   ==     +---O----+
   |                                      |          |
   |                                      R          |
   |                                      |          |
  GND                                    GND        GND

von Andreas F. (aferber)


Lesenswert?

Kay Imperator schrieb:
> Wenn ich mich recht entsinne, gab es da in der Übertragungs-Schicht auch
> großzügige Hemmingdistanzen und selbstheilende Datenkodierung mit
> reichlich Redundanz ;)

Bei SCSI? Nö. Die einzige Absicherung gegen Übertragungsfehler war ein 
Parity-Bit. Selbst ein simpler CRC kam erst sehr viel später mit 
Ultra-160-SCSI, das war aber dann auch schon LVD. Im Highend-Umfeld 
(Grossrechner etc.) hat SCSI aber auch von Anfang an mit differentieller 
Übertragung gearbeitet (damals noch High Voltage Differential), alleine 
schon, weil damit längere Kabel (bis 25m) möglich waren.

ATA hatte dagegen nichtmal Parity. Erst mit Ultra-ATA/33 im UDMA2-Modus 
kam dann ein CRC dazu.

Eine Fehlerkorrektur kennen beide nicht (nur Recovery - der Host sendet 
halt die Daten noch einmal), wäre aber IMO in diesem Fall auch 
überflüssiger Aufwand, solange Fehler nicht allzu häufig auftreten.

Andreas

von Yaro (Gast)


Lesenswert?

Ich werde es dann zuerst mit Serienterminierung versuchen, einen 
Kondensator gegen GND werde ich nur dann drauf machen, wenns nicht 
anders geht.
Ansonsten eben noch jede zweite Leitung GND, ist ja auch eine kleine 
Erhöhung der Kapazität.

Danke für eure Hilfe!

Gruß, Yaro

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>> Den richtigen SPI-Modus verwenden.
> Das mache ich...
> Sonst würde ja überhaupt nix sinvolles übertragen werden.
Ja, da kann man sich aber arg täuschen...
Ich behaupte dass genau so was wie du es beschreibst passieren kann, 
wenn du den falschen SPI-Modus verwendest. Denn wenn Sample- und 
Shift-Flanke vertauscht sind, hilft dir nur noch eine geringfügig 
unterschiedliche Laufzeit....  :-o

von Kay I. (imperator)


Lesenswert?

Yaro schrieb:
> Kondensator gegen GND werde ich nur dann drauf machen, wenns nicht
> anders geht.

Das ist ein RC-Glied - das R gegen GND wird nur ab Frequenz x 
nennenswert wirksam.

von Yaro (Gast)


Lesenswert?

Die beschriebenen Probleme treten z.T. auch auf, wenn ich zwei ATmegas 
verwende, und genau gleich initialisiere (nur eben ein Master und ein 
Slave).
Sample und Shift-Flanken sind dann eindeutig gleich gesetzt.

Habe aber grade gemerkt, dass es (in meinen jetzigen Aufbauten) nur 
Probleme gibt, wenn ich unterschiedlich getaktete Controller miteinander 
Kommunizieren lasse. Ist es so, dass schneller getaktete ATmegas auch 
steilere Flanken machen? Oder ist das nur vom internen Treiber abhängig?

Gruß, Yaro

von Yaro (Gast)


Lesenswert?

Noch was... Die Probleme, die auftreten sind, dass Bytes z.t. nicht 
zuendegeshiftet werden. Reflektionen (auf der SCK-Leitung) würden aber 
doch genau zum Gegenteil führen... es würde zu viel geshiftet!
Langsamerer prescaler hilft wie gesagt auch nicht.

Gruß, Yaro

von Flo (Gast)


Lesenswert?

Lass mal deine SPI-Einstellungen sehen!

von spess53 (Gast)


Lesenswert?

Hi

Benutzt du Double Speed?

MfG Spess

von Yaro (Gast)


Lesenswert?

Nein, nicht double Speed.

Das, wo es vorkommt, ist z.B. ein LCD-Debug-Board. Habe ein Board, auf 
dem ich ein LCD-Display drauf habe, was ich mit I2C und SPI ansteuern 
kann.

Ansteuerroutinen (Ausschnitt):
1
void lcdSPIInit(uint8_t operation){ //1: save SPI-settings, Init lcd SPI; 0: restore SPI
2
  static uint8_t spcr, spiDDR, csDDR;
3
4
  if(operation == 1){
5
    spcr = SPCR;
6
    spiDDR = SPI_DDR;
7
    csDDR = CHIPSELECT_DDR;
8
9
    CHIPSELECT_DDR |= (1<<CHIPSELECT_PIN);
10
11
    SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
12
    SPI_DDR |= (1<<MOSI_PIN) | (1<<SCK_PIN);
13
//    SPI_DDR &= ~(1<<MISO_PIN);
14
    CHIPSELECT_PORT &= ~(1<<CHIPSELECT_PIN);
15
  }else if(operation == 0){
16
    CHIPSELECT_PORT |= (1<<CHIPSELECT_PIN);
17
    _delay_us(1);
18
 //   CHIPSELECT_DDR = csDDR;
19
    SPI_DDR = spiDDR;
20
    SPCR = spcr;
21
  }
22
23
}
24
25
26
void lcdSPI_string(char *data){    //Char-Array ausgeben
27
  lcdSPIInit(1);
28
  while(*data){
29
    SPDR = *data;
30
    while(!SPI_READY);
31
    CHIPSELECT_PORT |= (1<<CHIPSELECT_PIN);
32
    _delay_us(10);
33
    CHIPSELECT_PORT &= ~(1<<CHIPSELECT_PIN);
34
    data++;
35
  }
36
  SPDR = '\0';
37
  while(!SPI_READY);
38
  CHIPSELECT_PORT |= (1<<CHIPSELECT_PIN);
39
  _delay_us(10);
40
  CHIPSELECT_PORT &= ~(1<<CHIPSELECT_PIN);
41
  SPDR = 2;        //Steuerzeichen
42
  while(!SPI_READY);
43
  lcdSPIInit(0);
44
  _delay_ms(5);
45
}

Empfängerroutinen (Ausschnitt):
1
void SPIInit(void){
2
  DDRB &= ~0x2C;  //SCK,MOSI,SS is Input
3
  //DDRB |= 0x10;   //MISO Output
4
5
  SPCR = (1<<SPIE) | (1<<SPE);
6
}
7
8
9
ISR(SPI_STC_vect){
10
  extern uint8_t data, bufpos;
11
  extern char buf[17];
12
13
  data = SPDR;
14
15
  if(data <= 31 && data != 0){
16
    switch(data){
17
      case 1:
18
        lcd_data(buf[0]);
19
      break;
20
      case 2:
21
        lcd_string(buf);
22
      break;
23
      case 3:
24
        lcd_clear();
25
      break;
26
      case 4:
27
        lcd_set_cursor(buf[0]-40, buf[1]-40);
28
      break;
29
      case 5:
30
        PORTC |= 0x08;  //Hintergrundbeleuchtung an
31
      break;
32
      case 6:
33
        PORTC &= ~0x08;  //Hintergrundbeleuchtung aus
34
      break;
35
      default: lcd_string("SPI-ERROR!!");
36
    }
37
    bufpos = 0;
38
  }else if(bufpos < 16){
39
      buf[bufpos++] = data;
40
  }
41
}

Wenn ich die Kabel knicke, oder mit trockenen Fingern die Pins 
überbrücke, kommt es z.T. öfter zu Störungen. Manchmal gibt es auch 
überhaupt keine Störungen.
Hängt auch ein Bisschen von den Platinen ab, von denen aus ich sende 
(bei gleichem Controller)

Gruß, Yaro

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.