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
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
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
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
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
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
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 ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.