Empfangen mit SPI

Gast #3572308
Lesenswert?

Hallo, ich habe eine Frage zum SPI-Modul bei einem dsPIC33. Was ich tun 
möchte, ist beim Ausschalten des PICs Daten an einen externen 
EEPROM-Speicher zu senden und diese dann beim Einschalten wieder 
auszulesen. Das Senden bzw Schreiben funktioniert und auch beim Auslesen 
sehe ich am Oszi, dass die Daten aus dem EEPROM am SDI-Pin des Pics 
ankommen. Leider gelingt es mir dann nicht diese Daten in einer 
Variablen zu speichern. Mein Code zum Auslesen sieht so aus:
1
temp = SPI2BUF;                 //Buffer auslesen, damit SPIRBF = 0
2
SPI2BUF = 0b00000000;           //irgendetwas senden, um Clock auszugeben
3
while(!SPI2STATbits.SPIRBF);    //Warten bis alle Bits gesendet/empfangen sind
4
variable = SPI2BUF;             //Buffer auslesen
Vorher setze ich natürlich auch noch das entsprechende CS-Bit zu Null. 
Der PIC ist dabei Master, der Speicher Slave und der SS2-Pin über einen 
Widerstand mit Ground verbunden. In der Variablen steht immer Null nach 
dem Auslesen.

Wäre für den ein oder anderen Tipp wirklich sehr dankbar!
Gast #3572555
Lesenswert?

Danke für das PDF.. das kannte ich bis jetzt noch nicht. Aber ich bin 
der Meinung, dass ich alles so umgesetzt habe.. auf Basis des 
Datenblatts. Und ich sehe ja auch am Oszi, dass sowohl das Schreiben als 
auch das Lesen funktioniert. Das Problem ist, dass ich die Daten, die 
vom EEPROM am SDI-Pin meines PICs ankommen, nicht in die entsprechende 
Variable geschrieben bekomme.
Gast #3572732
Lesenswert?

habe ein kleines Test-File mit den relevanten Schritten 
zusammengestellt. Die Daten sind bereits im EEPROM gespeichert. In 
meiner While-Schleife lese ich diese Daten aus (2x8bit) und setze sie zu 
einer 16bit Variablen zusammen, die ich dann zum Testen wieder über SPI 
ausgebe (ohne einen Slave über CS zu aktivieren). Am Oszi sehe ich, dass 
das Auslesen des EEPROM funktioniert (die entsprechenden Bits sind am 
Oszi auf High). Leider wird aber in der Variablen nichts gespeichert, da 
alle Bits Null sind, wenn ich diese ausgebe.
Angehängte Dateien:
(Firma: www.pcb-devboards.de) #3572798
Lesenswert?

Vielleicht liegen hier die Probleme:
1
ANSELB = 0; //Analog PINs auschalten

und hier:
1
PORTBbits.RB5=0; //CS-Bit

sollte eigentlich so stehen, du willst ja CS-PIN nicht abfragen sondern 
ansteuern:
1
LATBbits.LATB5=0; //CS-Bit

So auf die schnelle aufgefallen...

Gruß
Hermann
Gast #3572857
Lesenswert?

Hallo,

ich habe die entsprechenden Stellen angepasst.. leider ist das Ergebnis 
immer noch gleich. Der Speicher gibt das Bit-Muster korrekt aus, aber 
die Bits landen nicht in der entsprechenden Variablen im PIC.
Gast #3573092
Lesenswert?

Mein EEPROM unterstützt nur 8bit Kommunikation. Deshalb wähle ich 
zunächst den 8bit-Modus um zwei 8bit-Variablen (var_l und var_h) aus dem 
EEPROM in den Controller einzulesen. Dann setze ich diese beiden 
Variablen zu einer 16bit-Variablen (var) zusammen und stelle 
anschließend mein SPI-Modul auf 16bit um die Variable testweise zu 
senden. Also ist mein SPI2BUF beim Einlesen 8bit und beim Auslesen 
16bit. Das müsste doch gehen oder übersehe ich irgendetwas?

Das Auslesen mit Temp ist nur zum Löschen des SPIRBF-Bits. Sonst 
verwende ich doch eigentlich alle Variablen oder welche werden vom 
Compiler weg optimiert?
(Firma: www.pcb-devboards.de) #3573121
Lesenswert?

Wenn am SDI-Pin (Pic Seite) wirklich was ankommt, dann muss es 
funktionieren. mach doch mal Screenshot (Oszi) von deinem SDI + SCKL 
zusammen.

Beispiel:

http://ww1.microchip.com/downloads/en/DeviceDoc/CE313%20SPI%20Master%20EEPROM.zip
1
   // Read MS byte from EEPROM address.
2
    var =  EEPROMReadByte(0x10);
3
    var = (var<<8) & 0xff00;
4
    // Read LS byte from EEPROM address.
5
    var |= (EEPROMReadByte(0x11) & 0x00ff);
6

7

8
unsigned char EEPROMReadByte(unsigned int Address)
9
{
10
  unsigned char Local_8;
11

12
    LATBbits.LATB5=0;
13

14
    Local_8 = writeSPI2(0b00000011);
15

16
    Local_8 = writeSPI2((unsigned char)((Address>>8)&0x00ff));
17
    Local_8 = writeSPI2((unsigned char)(Address&0x00ff));
18

19
    Local_8 = writeSPI2(0);
20

21
    LATBbits.LATB5=1;
22

23
    return Local_8;
24
}
25

26

27
unsigned char writeSPI2( unsigned char i )
28
{
29
    SPI2BUF = i;          // write to buffer for TX
30
    while(!SPI2STATbits.SPIRBF);  // wait for transfer to complete
31
    return SPI2BUF;            // read the received value
32
}//writeSPI2

Gruß
Hermann
Gast #3573206
Lesenswert?

Sorry für den etwas unkonventionellen Screenshot;)

zur Erklärung: blau ist CLK, violett SDO und grün SDI. Alle Signale sind 
direkt an den PINS des Controllers gemessen. Ich gebe zuerst den Befehl 
zum lesen (0b00000011), gefolgt von der Adresse (0b00000000). 
Anschließend lese ich in diesem Beispiel jetzt mehrere Bytes 
hintereinander aus. Das SDO Signal entspricht dabei genau den Werten, 
die ich vorher in den Speicher geschrieben habe.
Angehängte Dateien:
Gast #3573421
Lesenswert?

ich hab den Fehler gefunden. hab das ganze im Steckbrett aufgebaut und 
der Pin den ich als SDI gewählt hatte war abgeknickt.. er hat also nicht 
im Steckbrett gesteckt.. :(

trotzdem Danke für eure Unterstützung!
Gast #3574074
Lesenswert?

Hätte noch ein Panorama machen können^^ aber hast schon Recht.. etwas 
kleiner wäre sinnvoller..

Eine Frage dann doch noch zum SPI.. ich nutze ja momentan normale 
I/O-Pins für meine CS-Signale, d.h. ich benötige den SS2-Pin eigentlich 
nicht. Im Datenblatt steht aber, dass man einen Pulldown-Widerstand (bei 
CKP=0) mit SSx verbinden soll, wenn man den "non-framed-3-wire-mode" 
nutzt. Da ich mit Pins aber eh schon relativ knapp bin, würde ich den 
Pin gerne andersweitig als normalen I/O nutzen. Ist es möglich, den SS2 
einfach nicht zu programmieren, oder kommt mein SPI dann durcheinander, 
wenn der SS2 nicht existiert?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren