PIC SPI-Receive liefert immer null

Gast #5373699
Lesenswert?
• ▲
▼
Hallo,

ich nutze gerade das erste Mal den SPI Modus des MSSP eines PIC18F.

Testweise wird ein Register des (Slave-) Chips beschrieben und dann 
wieder ausgelesen. Auf dem Oszi sieht das ganze auch gut aus (Befehl 
wird empfangen und es wird korrekt geantwortet).

In der Software allerdings gibt mir meine SPI-receive Funktion immer 
0x00 zurück. Mir gehen mittlerweile die Ideen aus, an welchen Stellen 
ich weiter nach Fehlern suchen sollte.

Ich habe bereits folgendes probiert:

- SPI Modus von 0 auf 1 geändert (2 und 3 lassen sich ausschließen)
- PPS geprüft; die Anschlusszuordnungen sind korrekt

-> Im Datenblatt wird angedeutet, dass es einen Unterschied zwischen 
Senden und Empfangen gibt, allerdings finde ich keine Möglichkeit ein 
Empfangen anzustoßen ohne Dummy-Daten zu senden.

Ich hoffe ihr könnt mir helfen :).
1
void main()
2
{
3
  [...]
4
    SRAM_CS = 0;
5
    spi_transmit(0x05); // Read Mode Register
6
    uint8_t mode_register = spi_receive();
7
    SRAM_CS = 1;
8
  [...]
9
}
1
uint8_t __inline spi_receive() // <-- liefert immer null?!
2
{
3
    SSP2BUF = 0x00;// transmit dummy data
4
    while(!SSP2IF)
5
        ;
6
    SSP2IF = 0;
7
    return SSP2BUF;
8
}
Gast #5373713
Lesenswert?
• ▲
▼
Bräuchten ein paar mehr Infos.
Init der SPI.
Init der GPIO. Klassiker hast du auch die entsprechenden GPIO Pins als 
Ausgang bzw. als Eingang konfiguriert. ?
Ist der uC SPI Master oder Slave. Was für ein Chip hängt als Slave am 
SPI-Bus ?
Gast #5373721
Lesenswert?
• ▲
▼
Der Chip wird im Master Mode betrieben. Es soll ein SRAM (23LC1024) 
angesteuert werden.

volksvorg schrieb:
> Init der SPI.
1
void spi_init(uint8_t spi_mode)
2
{
3
    SSP2STATbits.CKE = !(spi_mode       & 0x01);
4
    SSP2STATbits.SMP =  (spi_mode >> 1) & 0x01;
5
    
6
    SSP2CON1 |= 0x02; // Mode: SPI Master; Clock = Fosc/64
7
    SSP2CON1 |= _BS(5); // Enable MSSP2
8
}


volksvorg schrieb:
> Init der GPIO.
1
/* MSSP2 SPI */    
2
    LATB  &= ~ _BS(2); // Idle Level: Low
3
    TRISB &= ~ _BS(2); // SPI_CLOCK Output
4
    TRISB &= ~ _BS(3); // SPI_SO Output
5
    TRISB |=   _BS(1); // SPI_SI Input
6
    LATB  |=   _BS(0); // SPI_CS = High (unselect slave)
7
    TRISB &= ~ _BS(0); // SPI_CS Output

SPI Transmit sieht folgendermaßen aus:
1
void __inline spi_transmit(uint8_t data)
2
{
3
    SSP2BUF = data;
4
    while(!SSP2IF)
5
        ;
6
    SSP2IF = 0;
7
    // Read SSP2BUF to clear the Buffer Full (BF) Bit
8
    uint8_t trash_data = SSP2BUF;
9
}

Das mit dem FIFO gucke ich mir gleich nochmal an. Danke :).
Gast #5373769
Lesenswert?
• ▲
▼
Wie hast du Chip Select gelöst? Ist eine weile her das ich mit PICs 
gearbeitet habe. Generell Vor dem Lesen muss CS HIGH sein. Um lesen zu 
können ziehst du CS auf LOW sendest vom Master Dummy Daten und zwar 
solange du Daten lesen möchtest. Und wenn du fertig bist ziehst du CS 
wieder auf HIGH. Z.B. Datenwort 16Bit. und du möchtest 1 Datenwort 
einlesen.
1
CS auf LOW. 
2

3
SPI_recieve();
4

5
CS auf HIGH

bei Zwei Datenworte
1
CS auf LOW. 
2

3
SPI_recieve();
4
SPI_recieve();
5

6
CS auf HIGH

usw.
Gast #5376305
Lesenswert?
• ▲
▼
Guten Abend,

danke für die Hinweise. Es gibt aber kein Problem mit dem Empfangen an 
sich.

Der Chip sendet als Antwort auf den Lese-Befehl 0x80. Der PIC liefert 
als empfangenen Wert aber immer 0x00 (anstatt 0x80), unabhängig von den 
(laut Oszi) tatsächlich empfangenen Daten.
Gast #5377718
Lesenswert?
• ▲
▼
Volker S. schrieb:
> Der unbekannte PIC hat auf dem Pin für den SPI Eingang eine
> Analogfunktion, die nicht deaktiviert wurde?
>
> So, oder ähnlich...ANSELBbits.ANSB2 = 0;

Gute Idee, leider ist das die richtige Lösung.

Das dürfte aber eigentlich nicht der Fall sein, denn ich habe alle 
Analogen Eingänge deaktiviert:
1
[Etwas über dem I/O-Setup vom MSSP2]
2
/* Disable ALL analog functions */
3
    ANCON0 = 0xFF;
4
    ANCON1 = 0x1F;

Ich habe einfach mal hinter der Init-Routine einen Breakpoint gesetzt 
und nachgesehen was in den ANCONx Registern drinsteht. Es sind nicht die 
obigen Werte. Nach etwas gesuche habe ich festgestellt, dass ein 
Programmteil diese Werte (falsch) neu schreibt. Wow. Ich stell mich dann 
mal in die Ecke.

danke :D

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