Forum: Mikrocontroller und Digitale Elektronik Pic SPI Read immer 0


von Dominic A. (neo123)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

Ich habe ein kleines Problem mit meiner SPI Read Routine.
Folgendes Problem: Ich sende einen Befehl an einen Flash Speicher 
welcher anschliessend Antworten sollte. Wenn ich den Bus mit dem LA 
ansehe funktioniert auch alles. Das Byte 0x05 wird gesendet und 
anschliessend wird auch ein Byte 0x1E aus dem Flash herausgeclockt. 
Jedoch sehe ich das empfangene Byte nur auf dem LA. Der Pic selber liest 
aber immer eine 0. Ich verwende einen PIC18F26J11.

Könnte sich jemand kurz die Read Routine ansehen und mir sagen ob er 
einen Fehler findet? Ich selber sehe keinen.

Read Funktion:
1
unsigned char SPI_Read(void)
2
{
3
        unsigned char TempVar;
4
        TempVar = SSP2BUF; //Löschen des BF-Flag
5
        SSP2IF = 0; //Interrupt Flag löschen
6
        SSP2BUF = 0x00; //Clock mit Dummy Bit
7
        while (!SSP2STATbits.BF); // Warten bis gesendet
8
        return (SSP2BUF); // Wert zurückgebebn
9
}
1
unsigned int flash_readstatus(void)
2
{
3
    unsigned int state;
4
    CE_Flash = 0;
5
    SPI_Write(0x05);
6
    state = SPI_Read();
7
    CE_Flash = 1;
8
    return state;
9
}
Flash Funktion:

von Master S. (snowman)


Lesenswert?

kann es sein, dass dein slave anstatt 0x00 ein 0xFF erwartet, während er 
senden soll? ansonsten sieht dein code auf die schnelle nicht falsch 
aus.

von Rainer U. (r-u)


Lesenswert?

Leg doch mal die Miso statisch auf H, und dann feil an Deinem Programm 
bis FF zurückkommt.. Dann hast Du zumindest irgendwelche Timingeffekte 
ausgeschlossen.

von SPI dummie (Gast)


Lesenswert?

Hi Dominic A.

hast du inzwischen eine Lösung für dein Problem gefunden? Ist stehe vor 
dem selben Problem. Ich verwende einen PIC16LF1709. Senden der Daten 
klappt alles, richtige Antwort steht auch am PIN an (LA). Jedoch ließt 
der PIC immer eine 0.

von Max H. (hartl192)


Lesenswert?

Ich hab das Dateblatt jetzt nicht zur Hand, würde aber schätzen dass du 
den Eingang als analog eingestell haben könntest.

Poste vllt. auch mal deinen Schaltplan und Quellcode.

von SPI dummie (Gast)


Lesenswert?

Mein code sieht folgendermaßen aus,

//Initialisierung des SPI-Buses -> MC = Master ; Bsens = slave
void initSPI(void)
{
    SPI_CS_bsens = 1;               //init idle value CS --> bsens off
    LATBbits.LATB4 = 1;             //init idle value CLK
    LATBbits.LATB5 = 1;             //init idle value SDO
    LATBbits.LATB6 = 1;

    ANSELCbits.ANSC2=0;             //Digital on
    //Engänge und Ausgänge des SPI-Busses definieren
    TRISCbits.TRISC2=0;             //Ausgang RC2 -> CS
    TRISBbits.TRISB4=0;             //Ausgang RB4 -> CLK
    TRISBbits.TRISB5=0;             //Ausgang RB5 -> SDO
    TRISBbits.TRISB6=1;             //Eingang RB6 -> SDI

    RB4PPS = 0x10;                  //PORTbelegung CLK
    RB5PPS = 0x12;                  //PORTbelegung SDO


    /*SPI Mode 1,0*/

    SSP1CON1 = 0b00010000;      // Clock = FOSC/4 und CKP = 1 (Idle is 
high)
    SSP1STATbits.CKE = 0;       // CKE = 0
    SSP1STATbits.SMP = 1;   //1=INPUT data sampled at end of data output 
time
    SSP1CON1bits.SSPEN = 1;     // SPI Modul nur einschalten wenn nötig

    PIE1bits.SSP1IE = 1;
    INTCONbits.GIE = 1;


}



//---------------------------------------------------------------------- 
-----
//SPI Singelübertragung, schreiben und lesen. Adresse und Data muss 
übergeben werden
unsigned char SPI_s_rtx_bsens(unsigned char reg_id, unsigned char data)
{
    unsigned char dummy;
    SPI_CS_bsens = 0;               //Übertragung freigeben

    SSP1BUF = reg_id;                //Adresse übertragen

    while(!SSP1STATbits.BF);         //Übertragung fertig
    while(!PIR1bits.SSP1IF);         //Interrupt gesetzt?
    PIR1bits.SSP1IF = 0;             //Interrupt zurücksetzten

    dummy = SSP1BUF;                 //SSP1BUF sicher leeren

    SSP1BUF = data;                  //Daten übertragen

    while(!SSP1STATbits.BF);         //Übertragung fertig
    while(!PIR1bits.SSP1IF);         //Interrupt gesetzt?
    PIR1bits.SSP1IF = 0;             //Interrupt zurücksetzten

    dummy = SSP1BUF;                 //Daten lesen

    SPI_CS_bsens = 1;                //Übertragung sperren
    return(dummy);                   //Daten zurückgeben
}

von SPI dummie (Gast)


Lesenswert?

Der SDI Eingang ist bei diesem PIC leider kein Analogeingang dadurch 
fällt deine Lösung leider flach.

von neuer PIC Freund (Gast)


Lesenswert?

Beim sdcc:
1
volatile unsigned char dummy;

Ansonsten wird der dummy-read wegoptimiert.

von Max H. (hartl192)


Lesenswert?

SPI dummie schrieb:
> Der SDI Eingang ist bei diesem PIC leider kein Analogeingang dadurch
> fällt deine Lösung leider flach.
An welchen Pin hast du den SDO des Slaves dann gehängt? Schaltplan?

Laut Datenblatt* Seite 6 ist SDI (nach dem Reset) auf RB4 und der ist 
auch AN10. Oder hast du das irgendwo in nicht gezeigtem Code geändert?

*http://ww1.microchip.com/downloads/en/DeviceDoc/40001729B.pdf

: Bearbeitet durch User
von PIC N. (eigo) Benutzerseite


Lesenswert?

Das klingt nach dem selben Problem, wie ich es auch mal hatte. Schau mal 
hier: http://pic-projekte.de/phpBB3/viewtopic.php?f=39&t=477#p6499

: Bearbeitet durch User
von SPI dummie (Gast)


Lesenswert?

Danke für die vielen Rückmeldungen. Ich habe meinen SDI Eingang auf RB6 
gelegt. Im Datenblatt hab ich zumindest einmal Festgestellt des der SDI 
Eingang auf Seite 6 auf RB4 liegt und auf Seite 15 auf RB6. Werde 
versuchen die beiden zu tauschen (geätzte Platine), da dieser SDI PIN 
meines Erachtens nach nicht frei wählbar ist (Seite 141).

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.