hallo
Ich habe ein Problem mit SPI-Interface. Die Daten die von Slave gesendet
wird, werden nicht richtig über MISO-Leitung Übertragen. Das Problem
Wahrscheinlich mit SPDR-Register. Im Anhang ist ein Bild, das vergleicht
die Data auf Slave und Master Seite. Die Daten auf Slave-Seite sind
richtig, aber die auf Master-Seite sind verfälscht. Manchmal gibt 5 aus
und 5 ist die Zahl die ich von Master zu Slave schicke. kann jemand mir
schreiben, wie kann ich das Problem aufheben
Vielen Dank
mein Code:
Masterseite:
void KONF_SPI_MASTER() {
DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2);
DDRL |= (1 << DDL3); // SS(NANO) als Ausgang
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
SPCR &= ~((1 << SPR1) | (1 << CPOL) | (1 << CPHA));
SPSR = 1 << SPI2X;
PORTB |= (1 << PORTB0); // SS (MCP3204) HIGH setzen
PORTL|=(1<<PORTL3); //SS (NANO) High setzen
}
void READ_Data_NANO(uint8_t DW) {
PORTL&=~(1<<PORTL3); //SS (NANO) lows etzen
SPDR = DW;
while (!(SPSR & (1 << SPIF)));
result_MISO[0]=SPDR;
SPDR = DW;
while (!(SPSR & (1 << SPIF)));// warten
result_MISO[1]=SPDR;
SPDR = DW;
while (!(SPSR & (1 << SPIF))); // warten
result_MISO[2]=SPDR;
SPDR = DW;
while (!(SPSR & (1 << SPIF))); // warten
result_MISO[3]=SPDR;
SPDR = DW;
while (!(SPSR & (1 << SPIF))); // warten
result_MISO[4]=SPDR;
}
SLAVE-Seite
void Konf_SPI_SLAVE() {
DDRB |= (1 << DDB4); // MISO als Ausgang
SPCR |= (1 << SPE);
}
while (1) {
while (!(SPSR & (1 << SPIF))); //warten
SPDR = ADC_Ergebnisse[0];
while (!(SPSR & (1 << SPIF))); //warten
SPDR = ADC_Ergebnisse[1];
while (!(SPSR & (1 << SPIF))); //warten
SPDR = ADC_Ergebnisse[2];
while (!(SPSR & (1 << SPIF))); //warten
SPDR = ADC_Ergebnisse[3];
while (!(SPSR & (1 << SPIF))); //warten
SPDR = ADC_Ergebnisse[4];
}
Ja, ich habe auch gerade gesehen, dass die Einstellung gleich ist. Beim
Master löscht du die Bits explizit, beim Slave werden sie nicht gesetzt.
Allerdings sind auch die Clock-Rate Einstellungen unterschiedlich.
Mit welchen Frequenzen arbeiten Master und Slave jeweils (Oscillator)?
SCK Master ist auf fosc/8 eingestellt, SCK Slave auf fosc/4
Und: wie sieht die Verbindung der beiden Seiten aus? Langes Kabel? Wenn
ja, wie lang?
die CLOCK-Einstellung wird lediglich bestimmt durch den
Master-Teilnehmer. Über SCK-Pin kann ein Slave Teilnehmer. Ich verstehe
nicht warum du denkst, dass die beide unterschiedliche Frequenzen oder
Clock-Einstellung haben.
Wenn SCK-Einstellung mit fosc/8 ist, dann wird für beide gleich.
hobbyflieger schrieb:> und 5 ist die Zahl die ich von Master zu Slave schicke. kann jemand mir> schreiben, wie kann ich das Problem aufheben
DaBla lesen ?
SS Pin Functionality
hobbyflieger schrieb:> die CLOCK-Einstellung wird lediglich bestimmt durch den> Master-Teilnehmer. Über SCK-Pin kann ein Slave Teilnehmer. Ich verstehe> nicht warum du denkst, dass die beide unterschiedliche Frequenzen oder> Clock-Einstellung haben.
Jein. Der Master gibt natürlich die Clock vor. Ich weiss aber nicht, wie
SPI bei deinem Prozessor genau implementiert ist. Wenn man dem Slave
sagt, du hast mit max. 500 KHz zu rechnen, und jetzt kommt eine 1 MHz
Clock, kann es sein, dass die SPI Implementierung damit nicht klar
kommt.
Ich würde mal versuchen, die Clock so weit runter zu drehen wie möglich
(auf Master Seite).
z.B. auf fosc/128
was meinst du, ich verstehe dich nicht. ich habe oben SS als Ausgang
definiert, dass bei Datenübertragung SS auf LOW und danach wieder auf
HIGH setzen. PORTL|=(1<<PORTL3); habe ich auch in meiner Code nach der
SPI-Funktion.
hobbyflieger schrieb:> was meinst du, ich verstehe dich nicht. ich habe oben SS als Ausgang> definiert, dass bei Datenübertragung SS auf LOW und danach wieder auf> HIGH setzen. PORTL|=(1<<PORTL3); habe ich auch in meiner Code nach der> SPI-Funktion.
Sorry, übersehen.
Aber du kannst trotzdem beim Master MSTR bit in SPCR checken.
Ansonsten wirklich vorerst so langsam wie nur möglich und ohne
2x probieren.
Gutes Scope.
Man kann bei deiner Aufnahme leider weder die Spannungsskalierung noch
die Zeiteinstellung erkennen.
Erkennbar sind aber deutliche Überschwinger.
Setze mal 100 Ohm in die CLK und Datenleitungen (Serienterminierung).
Arbeiten beide Systeme mit der gleichen Versorgungspannung (5V
vermutlich), oder ist eines davon ein 3.3V System und das andere auf 5V?
Die Terminierungswiderstände immer auf der "sendenden" Seite einbauen.
Also CLK und MOSI auf der Master-Seite, MISO auf der Slave Seite.
hobbyflieger schrieb:> so sieht die Übertragung auf Leitungen. Grün: SCK, Gelb:MISO
Da werden aber 6 Bytes übertragen ?
Und zwar 0x08, 0x16, 0x0E, 0xA8, 0x5D, 0x05
wenn du meinst, das erste Bild, habe die Korrektur gemacht, dass SPI nur
5 Bytes sendet. ich hatte (while (!(SPSR & (1 << SPIF))); ) nach BYTE 5
, so hat SPI ein 6.BYTE gesendet. Das zweite Bild zeigt die Übertragung
mit 5 Bytes, aber das Problem ist trotzdem noch da.
ich habe 4 AD-Wandler(10Bit). Ich speichere jeweils die Daten in
ADC_ergebnisse[i](nur 8 Bit), die restliche 2 Bits für den jeweiligen
AD-Wandler wird in ADC_ergebnisse[4] gespeichert
hobbyflieger schrieb:> wenn du meinst, das erste Bild, habe die Korrektur gemacht, dass SPI nur> 5 Bytes sendet. ich hatte (while (!(SPSR & (1 << SPIF))); ) nach BYTE 5
Ok, wieso ist dann beim zweiten Bild result_MISO[3] == 0 ?
Dieser Wert taucht doch nirgends auf in deinen Tabellen.
Slave soll doch definierte Werte senden, so weisst du wenigstens was
der Master kriegen soll.
So ist es nur rumrätseln - in deiner Tabelle stehen ganz andere Werte
als auf dem Oszi...
Lass doch ADC vorerst raus.
Also ich weiß nicht, unter 'komplette Programme' verstehe ich etwas
anderes.
Manche kennen vielleicht diese Geschichte von Paul Watzlawick noch
nicht, ihnen zur Unterhaltung:
Um Mitternacht kriecht ein Betrunkener suchend auf allen Vieren unter
einer Straßenlaterne herum. Kommt ein Polizist vorbei: "Sie! Was machen
Sie denn da?" "Ich suche meinen Hausschlüssel." Jetzt suchen beide. Nach
erfolglosen zehn Minuten fragt der Polizist: "Sagen Sie mal, sind Sie
sicher, dass Sie Ihren Schlüssel hier verloren haben?" Kommt als
Antwort: "Nein, nicht hier, sondern dort drüben. Aber dort ist es viel
zu dunkel zum Suchen."
hobbyflieger schrieb:> er soll nur 51 senden über MISO-Leitung und 4> über MOSI-Leitung.
Nein.
Master sendet ständig z.B. 4 definierte Werte.
Slave sendet diese vorerst nur zurück - nicht mehr und nicht weniger.
Wenn das ohne Fehler abgeht, kann man weiter sehen.
hobbyflieger schrieb:> das Problem dass Slave falsche Ergebnisse sendet (siehe Anhang Grün:> MOSI , Gelb: MISO)
Ich sehe da 13 x OK, 1 x Fehler, 13 x OK, 1 x Fehler...
Vielen Dank für deine Hilfe.
das Problem vielleicht von Arduino NANO. Mit Arduino UNO sind die Fehler
weniger 1 Fehler/300 Byte.
wenn ich schreibe, wie du mir vorgeschlagen hast sind die Fehler 30
Fehler/300Byte.
es scheint mir aus, dass die Fehlübertragung nicht vollständig beseitigt
werden kann.