Forum: Mikrocontroller und Digitale Elektronik Leseprobleme beim PIC24F32KA304


von Holger W. (sirmortimer)


Lesenswert?

Hallo Leute,

ich habe da mal ein Problem mit der SPI-Schnittstelle bei einem 
Pic24F32KA304.

Ich muss Parameter auf einen LDC1000 (Inductance to Digital Converter) 
übertragen und auch wieder auslesen.
Das Übertragen klappt gut, und das Auslesen auf der LDC-Seite auch, im 
Logikanalysator kommen die Daten auch richtig an; bis zum PIC (ich habe 
direkt am PIC gemessen).
Leider landen die Daten nicht im Recieve-Buffer des PICs, denn beim 
Lesen des Buffers bekomme ich immer 0 als Ergenis.

Die Parameter des PICs und der Code ist wie folgt:

Register:

    SPI2CON1 = 0x053B;  // 16-Bit-Modus
    SPI2CON2 = 0x0001;
    SPI2STAT = 0x800C;

    TRISA = 0x0FC3;
    TRISB = 0xFC00;
    TRISC = 0x004B;

Code zum Schreiben / Lesen:

void SPI2_Exchange( uint16_t pTransmitData, uint16_t pReceiveData )
{

    uint16_t Dummy;

    while( SPI2STATbits.SPITBF == true )
    {

    }

    if (SPI2_TransferModeGet() == SPI2_DRIVER_TRANSFER_MODE_16BIT)
        SPI2BUF = pTransmitData;
    else

  SPI2BUF = pTransmitData;

    while ( SPI2STATbits.SRXMPT == true);

    if (SPI2_TransferModeGet() == SPI2_DRIVER_TRANSFER_MODE_16BIT)
        pReceiveData = SPI2BUF;
    else
        pReceiveData = SPI2BUF;

}

Kann mir einer sagen, was ich da übersehe?

Vielen Dank schon mal im Voraus, Holger

: Bearbeitet durch User
von Klaus (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab vor kurzem was mit dem PIC24FV32KA302 gemacht. Ist ja eigentlich 
das gleiche Teil nur im kleiner Gehäuse, und dachte mir ich könnte 
helfen.

Dann hab ich das gelesen

Holger W. schrieb:
>     SPI2CON1 = 0x053B;  // 16-Bit-Modus
>     SPI2CON2 = 0x0001;
>     SPI2STAT = 0x800C;
>
>     TRISA = 0x0FC3;
>     TRISB = 0xFC00;
>     TRISC = 0x004B;

Ich müsst jetzt anfangen, die 16 Bit Hexwerte auf die verschiedenen 
Registerfunktionen aufzuteilen um zu sehen, was wo eingestellt wird. Das 
kann man doch über die vordefinierten Bitfelder transparent und leicht 
lesbar machen. Wie das geht zeigst du ja hier

>     while( SPI2STATbits.SPITBF == true )

Um ehrlich zu sein, ich bin zu faul mir deine Initialisierung anzusehen 
und zu überprüfen.

MfG Klaus

von sirmortimer (Gast)


Lesenswert?

Hallo Klaus,

Du hast recht, Hex zulesen ist etwas umständlich, ich habs halt so aus 
dem Code-Configurator kopiert. Hier der Klartext:

CON1-Register:

DISSCK = 0
DISSDO =  0
MODE16 = 1
SMP = 0
CKE = 1
SSEN = 0
CKP = 0
MSTEN =1
SPRE2 = 1
SPRE1 = 1
SPRE0 = 0
PPRE1 =1
PPRE0 = 1

Im Con2-Register habe ich nur das SPIBEN-Bit gesetzt.
Im Status-register ist folgendes gesetzt:

SPIEN = 1
SISEL1 = 1
SISEL0 = 1

Ich hoffe die Information hilft Dir und ann mir weiter,

Grüße zurück, Holger

von Klaus (Gast)


Lesenswert?

sirmortimer schrieb:
> Du hast recht, Hex zulesen ist etwas umständlich, ich habs halt so aus
> dem Code-Configurator kopiert. Hier der Klartext:

Kann ich nicht erkennen. Klartext würde so aussehen:
1
SPI2CON1bits.DISSCK = 0; // warum ????
2
SPI2CON1bits.DISSDO = 0; // warum ???
3
SPI2CON1bits.MODE16 = 1; // will 16 Bit
4
....

aber jetzt dazu, Kommentare (und Formatierung) von mir
1
void SPI2_Exchange( uint16_t pTransmitData, uint16_t pReceiveData ) {
2
    uint16_t Dummy;  // warning never used
3
    while( SPI2STATbits.SPITBF == true ) {
4
                 // ich würd hier ein Semikolon spendieren
5
    }
6
    // warum das if?? Code wirkungslos
7
    if (SPI2_TransferModeGet() == SPI2_DRIVER_TRANSFER_MODE_16BIT) {
8
        SPI2BUF = pTransmitData;
9
    } else {
10
        SPI2BUF = pTransmitData;
11
    }
12
    while ( SPI2STATbits.SRXMPT == true);
13
         // hier würd ich, wie oben zwei {} spendieren
14
15
    // warum das if?? Code wirkungslos
16
    if (SPI2_TransferModeGet() == SPI2_DRIVER_TRANSFER_MODE_16BIT) {
17
        pReceiveData = SPI2BUF;
18
    } else {
19
        pReceiveData = SPI2BUF;
20
    }
21
    Nop();
22
    // und hier werden die gelesenen Daten mit dem
23
    // impliziten return geschreddert
24
}

Wenn man toten Code vermeidet, passt mehr auf eine Bildschirmseite und 
man kann das Programm besser überblicken. Ich hab mir außerdem erlaubt, 
einen Nop() einzufügen. Da kann man gut einen Breakpoint plazieren und 
sehen, ob im SPI2BUF das drin ist, was auf dem LA zu sehen ist.

MfG Klaus

von sirmortimer (Gast)


Lesenswert?

Hallo Klaus,

erstmal Danke für deine Antwort.

Mit der Funktion habe ich schon einige Versuche gestartet, dehalb ist 
dort der wirkunslose Code noch drinn. Ursprünglich ist die Funktion vom 
Codegenerator sowohl für den 16- als auch für den 8-Bit-Betrieb gedacht.

Ich verstehe nicht, warum gelesenen Daten geschreddert werden, wenn ich 
sie doch vorher in "pReceiveData" speichere und so zurückgebe? (ist so 
auch vom Codegenerator vorgegeben?)

Andererseits habe ich auch schon einen Breakpiont auf die Zeile
1
if (SPI2_TransferModeGet() == SPI2_DRIVER_TRANSFER_MODE_16BIT) {

gesetzt und mit F7 abgearbeitet. Dabei wurde aber nur 0 in 
"pReceiveData" gespeichert.


Du hast recht, da ich in diesem Fall nur 16-Bit-Modus benötige, kann ich 
die überflüssigen Zeilen weglassen.

Ich werden Dein Vorschläge morgen gleichmal umsetzen und mich dann mal 
melden.

Bis dann, Holger

von Klaus (Gast)


Lesenswert?

sirmortimer schrieb:
> Ich verstehe nicht, warum gelesenen Daten geschreddert werden, wenn ich
> sie doch vorher in "pReceiveData" speichere und so zurückgebe? (ist so
> auch vom Codegenerator vorgegeben?)

Ich denke, du solltest ein C-Buch zu Rate ziehen. Aber hier ein Hinweis

https://www.tutorialspoint.com/cprogramming/c_function_call_by_value.htm

und

https://msdn.microsoft.com/en-us/library/sta56yeb.aspx

MfG Klaus

von A. B. (Gast)


Lesenswert?

Man könnte natürlich (abgesehen von den Hinweisen auf eine halbwegs 
lesbare Formatierung und sinnvolle Kommentare; es ist schon eine 
Zumutung, so ein Spaghetti anderen vorzusetzen) auch das Suchen in der 
Literatur in gewisse Bahnen lenken: Call-by-reference vs. Call-by-value 
;-)

von Klaus (Gast)


Lesenswert?

A. B. schrieb:
> Literatur in gewisse Bahnen lenken: Call-by-reference vs. Call-by-value
> ;-)

Ach, du meinst den Link, den ich gepostet habe

Klaus schrieb:
> Ich denke, du solltest ein C-Buch zu Rate ziehen. Aber hier ein Hinweis
>
> https://www.tutorialspoint.com/cprogramming/c_function_call_by_value.htm

MfG Klaus

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.