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
> 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?
> 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
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
@ 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
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.
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
Dann werde ich zuerst jede zweite Leitung GND legen, wenns noch Störungen gibt, dann Terminierung. Danke für die schnellen Antworten! Gruß, Yaro
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.
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.
> > 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.
@ 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
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
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
>> 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
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.