Forum: Mikrocontroller und Digitale Elektronik SPI Master, PIC 2550, BF not set.


von BioSniper (Gast)


Lesenswert?

PIC2550. Das ganze läuft unter der USB-Firmware, ich denke aber nicht, 
dass es daran liegen kann.

Meine SPI-Übertragung funzt im Debugger nicht, er hängt sich auf bei:

=> while (!SSPSTATbits.BF); //rcvDataByte (Dummy) erwarten.

Solange das Buffer-Full-Bit 0 ist soll er dort warten.
Leider will er dort bis zum jüngsten Tag warten.

Hier habe ich auch schon alles durchgesehen zum SPI-Thema:

http://ww1.microchip.com/downloads/en/DeviceDoc/spi.pdf

SPI-Mode-1.1 MASTER ist bei mir eingestellt:

SSPCON1 = 0b00110001; //Enable SPI-1.1 Master (FOSC/16)
SSPSTAT = 0b01000000;

==============================================

void GetDataFromSPI (unsigned char Befehl) {
unsigned char varSSPBUF;

 varSSPBUF = SSPBUF;      //Receive/Send (BF)-Bit löschen.
 SSPBUF = Befehl;         //Befehl senden.
 while (!SSPSTATbits.BF); //rcvDataByte (Dummy) erwarten.
 varSSPBUF = SSPBUF;      //Receive/Send (BF)-Bit löschen.
}

==============================================

Anmerkungen:

WCol = 0 (immer 0, seh' ich ja im Watch-Fenster)

#define SetTRISB() TRISB = 0b11111111;  //TrisB Einstellung.
                  //RB0: 1; SPI: SDI Data IN
//RB1: 0; SPI: SCK Clock

#define SetTRISC() TRISC = 0b01111111;  //TrisC Einstellung.
                  //RC7: 0; SPI: SDO Data OUT

==============================================

Langsam habe ich das Gefühl, der Debugger müsste mal debugged werden.
Hab' mich schon dumm und dämlich nach dem Fehler gesucht.

Danke für die Hilfe

von holger (Gast)


Lesenswert?

#define SPI_WRITE(a) { SSPBUF=(a); while(PIR1bits.SSPIF==0); 
PIR1bits.SSPIF=0; }

Funktioniert immer.

von BioSniper (Gast)


Lesenswert?

Du meinst also, dass ich lieber das INT-Flag abfragen sollte, als das 
BF-Bit.
Werde es gleich mal versuchen, aber trotzdem würde es mich mal 
interessieren, warum es mit dem BF-Bit nicht geht (jedenfalls im 
Debugger nicht).

von BioSniper (Gast)


Lesenswert?

Ne, daran liegt es nicht, macht leider keinen Unterschied:

void GetDataFromMessPIC (unsigned char Befehl) {
unsigned char varSSPBUF;

 varSSPBUF = SSPBUF; //Receive/Send (BF)-Bit löschen.
 PIR1bits.SSPIF = 0;
 SSPBUF = Befehl;    //Befehl senden.
 while(!PIR1bits.SSPIF);
}

Es muss irgendwie daran liegen, dass das SPI-Ding nicht läuft.

Obwohl SSPEN = 1 ist:

//-----------------------------------------
//(M)SSP CONTROL REGISTER 1 (SPI-Mode).
//-----------------------------------------

//SD0 und SCK => Output

  SSPCON1 = 0b00110001; //Enable SPI-1.1 Master (FOSC/16).

/*
7. WCOL: Write Collision Detect bit (Transmit mode only)
 1 = The SSPBUF register is written while it is still
     transmitting the previousword (must be cleared in software).
 0 = No collision

6. SSPOV: Receive Overflow Indicator bit
   SPI Slave mode:
 1 = A new byte is received while the SSPBUF register
     is still holding the previous data. In case of
     overflow, the data in SSPSR is lost.
     Overflow can only occur in Slave mode. The user
     must read the SSPBUF, even if only transmitting
     data, to avoid setting overflow (must be cleared
     in software).
 0 = No overflow

5. SSPEN: Master Synchronous Serial Port Enable bit
 1 = Enables serial port and configures SCK, SDO,
     SDI & SS as serial port pins.
 0 = Disables serial port and configures these pins
     as I/O port pins.

4. CKP:   Clock Polarity Select bit
 1 = Idle state for clock is a high level
 0 = Idle state for clock is a low level

3-0. SSPM3:SSPM0: Master Synchronous Serial Port Mode
                  Select bits
 0101 = SPI Slave  mode, clock = SCK pin, SS pin control
        disabled, SS can be used as I/O pin.
 0100 = SPI Slave  mode, clock = SCK pin, SS pin
        control enabled
 0011 = SPI Master mode, clock = TMR2 output/2
 0010 = SPI Master mode, clock = FOSC/64
 0001 = SPI Master mode, clock = FOSC/16
 0000 = SPI Master mode, clock = FOSC/4
*/

//-------------------------------------
//(M)SSP STATUS REGISTER (SPI-Mode).
//-------------------------------------

 SSPSTAT = 0b01000000;

/*
7. SMP: Sample bit
  - SPI Master mode:
  1 = Input data sampled at end of data output time.
  0 = Input data sampled at middle of data output time.
  - SPI Slave mode:
  SMP must be cleared when SPI is used in Slave mode.
6. CKE: SPI Clock Select bit
  1 = Transmit occurs on transition from active to Idle
      clock state.
  0 = Transmit occurs on transition from Idle to active
      clock state.
5. D/A: Data/Address bit (I²C mode only)
4. P:   Stop bit (I²C mode only)
3. S:   Start bit (I²C mode only)
2. R/W: Read/Write Information bit (I²C mode only)
1. UA:  Update Address bit (I²C mode only)
0. BF:  Buffer Full Status bit (Receive mode only)
  1 = Receive complete, SSPBUF is full.
  0 = Receive not complete, SSPBUF is empty.
*/

von BioSniper (Gast)


Lesenswert?

Im ersten Posting hatte sich ein kleiner Fehler eingeschlichen, muss so 
lauten:

#define SetTRISB() TRISB = 0b11111101;
                  //Tris-RB0: 1; SPI: SDI Data IN
//Tris-RB1: 0; SPI: SCK Clock

von BioSniper (Gast)


Lesenswert?

Habe das Problem gelöst:

SPI wird von MPLAB-SIM nicht simuliert.

Man muss das SSPSTAT Register erst 2x manuell beschreiben im Watch 
Fenster, dann macht er das BF-Bit auf 1 und die Simulation läuft weiter.

von BioSniper (Gast)


Lesenswert?

Habs nochmal genauer gechecked:

SSPSTAT 1x beschreiben mit einer anderen Zahl als aktuell drin steht 
reicht, aber man darf nicht RUN nehmen, sondern F8, ob's auch mit F7 
geht habe ich nicht getestet, nehme ich aber mal an.

So eine Hühnerscheisse.

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.