Forum: Mikrocontroller und Digitale Elektronik PIC24 SPI slave


von Gast G. (john_wayne)


Lesenswert?

Hallo, ich versuche gerade das SPI modul von einem PIC24FJ64GB002 als 
slave zu programmieren. SDI-->RP0, SDO-->RP1, SCK-->RP3.
Meine Initialisierung sieht wie folgt aus:

TRISB = 0x000D; //RP0 in, RP1 out, RP2 in, RP3 in
RPINR20bits.SCK1R = 3; //Clock input at RP3
RPINR20bits.SDI1R = 0; //SDI at RP0
RPOR0bits.RP1R = 7; //SDO at RP1

SPI1BUF = 0; //Clear SPI Buffer
SPI1CON1bits.MSTEN = 0; //SPI in Slave mode
SPI1CON1bits.DISSDO = 0; // SDOx pin is controlled by the module
SPI1CON1bits.CKE = 0; // Serial output data changes on transition
                      // from Idle clock state to active clock state
SPI1CON1bits.CKP = 0; // Idle state for clock is a low level
                      // active state is a high level
SPI1CON1bits.MODE16 = 0; //byte-wide communication
SPI1CON1bits.SMP = 0; //Bit hast to be "0" in slave mode
SPI1CON1bits.SSEN = 0; //SS-Pin is not used for slave mode
SPI1STATbits.SPIROV = 0; //clear the Receive overflow flag
SPI1STATbits.SPIEN = 1; //enable SPI

Im Programm frage ich das SPIRBF Bit im Statusregister ab ob was 
empfangen wurde:

while (1){
      if ( SPI1STATbits.SPIRBF == 1) {  // Wait for incomming byte.
         buffer =  SPI1BUF;   // Store into buffer.
         ...
         ...
      }
}

Mein Problem ist, dass das SPIRBF bit nie gesetz wird, also nichts 
eingelesen wird.
Bin langsam am verzweifeln weil ich nicht finde woran das liegt, 
physikalisch liegen die Signale an den entsprechenden Pins.
Weis jemand was ich anders machen muss?

Danke schon mal im Voraus!
Gruß Eugen

von Dieter W. (dds5)


Lesenswert?

> RPINR20bits.SCK1R = 3; //Clock input at RP3
> RPINR20bits.SDI1R = 0; //SDI at RP0
> RPOR0bits.RP1R = 7; //SDO at RP1

Erzeugt der Compiler dazu automatisch die notwendigen unlock / lock 
Sequenzen?

Ich erinnere mich dunkel an irgendwelche __builtin... Funktionen (bei 
GCC)

von Michael H. (morph1)


Lesenswert?

tät auch sagen hier fehlt die unlock sequenz
1
  asm volatile ( "MOV #OSCCON, w1 \n"
2
  "MOV #0x46, w2 \n"
3
  "MOV #0x57, w3 \n"
4
  "MOV.b w2, [w1] \n"
5
  "MOV.b w3, [w1] \n"
6
  "BCLR OSCCON,#6");
7
    // unlock sequence

und danach wieder brav zusperren :)
1
  asm volatile ( "MOV #OSCCON, w1 \n"
2
  "MOV #0x46, w2 \n"
3
  "MOV #0x57, w3 \n"
4
  "MOV.b w2, [w1] \n"
5
  "MOV.b w3, [w1] \n"
6
  "BSET OSCCON,#6");
7
    // lock sequence

oder die im c30-compiler eingebauten funktionen durchsuchen, vl gibts da 
ein makro

von Master S. (snowman)


Lesenswert?

wieso nicht einfach Michrochips funktionen verwenden?
void OpenSPI1(unsigned int config1, unsigned int config2, unsigned int 
config3)

edit: such mal im installationspfad "...\Microchip\MPLAB 
C30\docs\periph_lib" nach der datei 
"dsPIC30F_dsPIC33F_PIC24H_SPI_Help.htm"

von Michael H. (morph1)


Lesenswert?

Wird ihm ohne richtig zugewiesene Pins auch nichts nutzen und bei den 
paar Registern ist man meist besser beraten wenn man die Fehler selbst 
macht, statt sich mit den Libs zu beschäftigen.

Und weil ichs grad sehe: TRIS-Zuweisungen sind unnötig, besser auf 1 
lassen wenn der Pin vom PPS (bzw dahinterliegender Peripherie) genutzt 
werden soll, das erledigt das Modul von selbst.

von Master S. (snowman)


Lesenswert?

ich weiss einfach, dass wenn ich die libs verwende, ich
a) sicher kein parameter vergesse, wenn ich alle parameter-
   möglichkeiten durchgehe, und
b) es optimal implementiert wird

ein SPI-modul wird sicher per default gewissen pins zugeteilt sein, die 
jedoch um-gemappt werden können. einfach mal mit den 
default-einstellungen testen ;-)

von Michael H. (morph1)


Lesenswert?

Master Snowman schrieb:
> ein SPI-modul wird sicher per default gewissen pins zugeteilt sein, die
> jedoch um-gemappt werden können.

Nö wirds leider nicht.

a) sowie b) sind nach einem Blick in die Lib leider nicht haltbar.

Aber ist ja auch egal, die Init-Routinen verwendet man sowieso meist nur 
einmal, da kommts auf Performance nicht an.

von Master S. (snowman)


Lesenswert?

@ Michael H.: du hast recht, bei diesem PIC sind keine SPI-pins per 
default schonmal vorab definiert :-( ...naja, bleibt nur noch die 
persönliche vorliebe wie man die module inizialisiert - geschmackssache 
halt ;-)

von Gast G. (john_wayne)


Lesenswert?

Hallo Michael,
ich habe jetzt die unlock und lock sequenzen eingefügt - leider ohne 
Erfolg :-(

Michael H. schrieb:
> Wird ihm ohne richtig zugewiesene Pins auch nichts nutzen

habe ich die Pins nicht richtig zugewiesen?

von Michael H. (morph1)


Lesenswert?

Also hier mal wie es erfolgreich in Betrieb habe, nutze allerdings das 
pps.h-file der Microchip-Libs um die PPS-Zuweisungen besser lesbar zu 
machen.

Musst du nur an deine Ansprüche anpassen.
1
void SPI1SlaveInit(void)
2
{
3
  SPI1BUF = 0;        // Clear the SPIxBUF register.
4
5
  // Write the desired settings to the SPIxCON1 and SPIxCON2 registers with MSTEN (SPIxCON1<5>) = 0.
6
  SPI1CON1bits.SMP = 0;    // Clear the SMP bit.
7
  SPI1CON1bits.CKP = 0;    // Idle Clock is low
8
  SPI1CON1bits.CKE = 0;    // 
9
  // If the CKE bit is set, then the SSEN bit must be set, thus enabling the SSx pin.
10
  SPI1STATbits.SPIROV = 0;  // Clear the SPIROV bit (SPIxSTAT<6>).
11
  SPI1CON1bits.MODE16 = 1;  // 16bit mode
12
  SPI1CON2bits.SPIBEN = 0;  // Select Enhanced Buffer mode by setting the SPIBEN bit (SPIxCON2<0>).
13
  SPI1CON1bits.SSEN = 0;    // Slave select enable
14
  SPI1STATbits.SPIEN = 1;    // Enable SPI operation by setting the SPIEN bit (SPIxSTAT<15>).
15
}
1
#include <pps.h>
2
3
void ppsInit(void)
4
{
5
  asm volatile ( "MOV #OSCCON, w1 \n"
6
  "MOV #0x46, w2 \n"
7
  "MOV #0x57, w3 \n"
8
  "MOV.b w2, [w1] \n"
9
  "MOV.b w3, [w1] \n"
10
  "BCLR OSCCON,#6");
11
  // unlock sequence  
12
13
  IN_FN_PPS_SDI1 = IN_PIN_PPS_RP2;    // SPI1SDI @ RP2
14
  OUT_PIN_PPS_RP1 = OUT_FN_PPS_SDO1;    // SPI1SDO @ RP1
15
  IN_FN_PPS_SCK1IN = IN_PIN_PPS_RP0;    // SPI1SCK @ RP0
16
17
  asm volatile ( "MOV #OSCCON, w1 \n"
18
  "MOV #0x46, w2 \n"
19
  "MOV #0x57, w3 \n"
20
  "MOV.b w2, [w1] \n"
21
  "MOV.b w3, [w1] \n"
22
  "BSET OSCCON,#6");
23
}

Und lass das TRIS-Register ruhig auf 0xFFFF, das PPS-Modul funktioniert 
auch ohne Zuweisung einer Richtung, wird automatisch gesetzt. Bin eher 
der Meinung, dass man sich hiermit Probleme einhandelt.

Gast G. schrieb:
> habe ich die Pins nicht richtig zugewiesen?

Bezog sich nur darauf, dass du ohne Unlock mit dem PPS nichts zuweisen 
kannst.

von Maik W. (werner01)


Lesenswert?

hallo,

hab hier nen code um im Master zu configuriern.
Vieleicht hilft es dir ja trotzdem(pic24hj12gp202)


memoryclear:
    mov    #0x800, w14
  clr  w0
    repeat  #256
    mov    w0, [w14++]
registerclear:
    clr   w0        ;reset w registers
    mov    w0, w14
    repeat  #12
    mov    w0, [++w14]
    clr    w14
constante:
  mov  #0x900-16,w0
  mov  w0,knobadress

  mov    #0b0000000000000000,w2
  mov    w2,OC1CON
pinremaping:
  mov    #0b0000011100000000,w2  ;sdo out on pin1
  mov    w2,RPOR0
  mov    #0b0000000000001000,w2  ;sck out on pin2
  mov    w2,RPOR1
  mov    #0b0001111100000000,w2  ;sdi in on pin 0
  mov    w2,RPINR20
spiconfig:
  mov  #0b0000000000111001,w1
  mov  w1,SPI1CON1
  clr  SPI1CON2
  bclr  SPI1STAT,#1      ;overflow clear
  bclr  SPI1STAT,#6
  bset  SPI1STAT,#15

und nur in asm viel Glück

von Gast G. (john_wayne)


Lesenswert?

Hallo, habs jetzt hinbekommen!
Ich glaube es lag daran das ich vergessen habe die Pins als I/O Pins zu 
configurieren, da die unprogrammiert analoge Eingänge sind.

Danke für die Hilfe!
Eugen

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.