Hallo Zusammen! Ich bin schon total verzweifelt! Hänge schon seit über einer Woche an einem Problem und bekomm dieses einfach nicht gebacken. Ich habe einen pic24fj128ga010. Diesen habe ich am SPI1 als Slave konfiguriert. Ich springe nachdem ich die SS Leitung abgefragt habe in die Routine und will die Daten die über SPI gesendet werden in Variablen ablegen. Es werden immer 16 Byte geschickt. Aber das Unterprogramm hängt immer an der folgenden Stelle: while (!SPI1STATbits.SPIRBF) set_bit(PORTA,0) ; Led leuchtet ständig und bringt mein ganzes restliches Programm zum erliegen. Anbei mal das Unterprogramm: void SPI1Service(void){ unsigned char SPI1[16]; int i; unsigned char rbuf = SPI1BUF; //Clear receive buffer full bit for(i=0; i<16;i++){ while (!SPI1STATbits.SPIRBF) set_bit(PORTA,0) ; //setze led0 clear_bit(PORTA,0); //lösche led0 SPI1 = SPI1BUF; } switch (SPI1[0]) { case 0x80 : Jahr = SPI1[1]; Monat = SPI1[2]; Tag = SPI1[3]; Wochentag = SPI1[4]; Stunde = SPI1[5]; Minute = SPI1[6]; Sekunde = SPI1[7]; break; case 0x81 : geobreit = (long)SPI1[1]<<24 | (long)SPI1[2]<<16 | (long)SPI1[3]<<8 | (long)SPI1[4]; geolaeng = (long)SPI1[5]<<24 | (long)SPI1[6]<<16 | (long)SPI1[7]<<8 | (long)SPI1[8]; break; case 0x82 : set_bit(PORTA,7); //Referenzflag break; } } Habe mit dem Oszi das senden der 16 Daten Bytes überprüft und diese werden korrekt übertragen. Danke für jede Hilfe! lG Daniel
Ich kenn jetzt die PIC24 nicht, aber ganz banal: 1) Slave nicht richtig konfiguriert 2) Takt kommmt nicht beim Slave an (oder zu schnell ?) 3) Slave Select irgendwas falsch Das wären so Möglichkeiten wo man suchen sollte. Noch paar kleine Anmerkungen: > unsigned char rbuf = SPI1BUF; //Clear >receive buffer full bit Warum wirfst du das erste Byte weg? > SPI1 = SPI1BUF; Sollte besser so aussehen SPI1[i] = SPI1BUF;
Hätte ich fast vergessen: Zähl doch in der for() Schleife mal mit ob überhaupt irgendwas ankommt. Oder Osci an Porta0 anschliessen.
Hallo Holger! Vielen Danke für deine schnelle Antwort! Ich bin mir eigentlich ziemlich sicher das ich den Slave Mode richtig konfiguriert habe. Takt kommt beim Slave an und auch die 16 Bytes werden korrekt übertragen. Der chip select eingang wird bei mir in der Endlosschleife in der main funktion ständig abgefragt und der Sprung an sich in das Unterprogramm klappt ja eigentlich. Das mit dem Oszi in der For Schleife ist ne gute Idee! Kann ich aber leider erst morgen ausprobieren, da ich grade kein Oszi zur Hand habe. Und du hast natürlich recht, das erste byte werfe ich weg. Frage mich auch gerade warum!! Ups! Vielleicht liegt es auch daran, kriegt ja dann keine 16 bytes mehr voll und hängt unter Umständen im letzten Durchlauf. Vielen Dank nochmal!!! Melde mich morgen wieder! lg daniel
Hallo! Du könntest auch noch überprüfen, ob die Bits in den CONFIG-Registern richtig gesetzt sind. Ich hatte vor einiger Zeit ein ähnliches Problem, das sich gelöst hat, als ich JTAG abgeschalten habe, da die SPI-Pins auf den JTAG-Pins lagen. Das sieht bei mir jetzt so aus:
1 | _CONFIG1(JTAGEN_OFF) |
Grüße, TommyS
Hallo! So habe jetzt mein Programm ein wenig geändert: void SPI1Service(void){ unsigned char SPI1[16]; int i; SPI1[0] = SPI1BUF; //Clear receive buffer full bit for(i=1; i<15;i++){ //SPI1BUF=0x00; while (!SPI1STATbits.SPIRBF) set_bit(PORTA,0) ; //setze led0 clear_bit(PORTA,0); //lösche led0 SPI1[i] = SPI1BUF; } switch (SPI1[0]) { case 0x80 : RTCCSetBinYear(SPI1[1]); RTCCSetBinMonth(SPI1[2]); RTCCSetBinDay(SPI1[3]); RTCCSetBinHour(SPI1[5]); RTCCSetBinMin(SPI1[6]); RTCCSetBinSec(SPI1[7]); RTCCSet(); break; case 0x81 : geobreit = (long)SPI1[1]<<24 | (long)SPI1[2]<<16 | (long)SPI1[3]<<8 | (long)SPI1[4]; geolaeng = (long)SPI1[5]<<24 | (long)SPI1[6]<<16 | (long)SPI1[7]<<8 | (long)SPI1[8]; break; case 0x82 : set_bit(PORTA,7); //Referenzflag break; } } Jetzt verhält es sich so: Wenn ich Daten schicke bleibt er zu 90% trotzdem noch in der while schleife hängen und auf dem Oszi beim Messen des PortA.0 erscheint nur eine steigende Flanke (also nicht ein Byte wird korrekt abgelegt). Allerdings kommt es jetzt vor, dass er es auch mal korrekt abarbeitet, zwar selten aber immerhin. Dann sind auch auf dem Oszi die einzelnen Bytes zu erkennen. Nur kann ich das so natürlich nicht lassen. Denke mir, dass es vielleicht irgend ein Zeitproblem gibt,aber warum kann ich dann nicht wenigstens ein paar bytes korrekt ablegen? Bin echt am Ende!! Hoffe ihr habt noch ne Idee was das sein!!! lg Daniel
Hallo Matthias! Hab das Errata durchgelesen, aber auch nichts weiter entdecken können. Collision Flag wird nicht gesetzt! Trotzdem danke für deine Antwort!!! Hat jemand vielleicht noch einen Einfall? lg daniel
Nochmal was zum nachdenken:
> SPI1[0] = SPI1BUF; //Clear receive buffer full bit
Woher weißt du das das erste Byte hier schon komplett
empfangen wurde? Du sagtest oben du fragst den
Slave Select Pin ab. Der sagt dir aber nicht ob
das Byte schon komplett übertragen wurde. Möglicherweise
stört dieses unkontrollierte Lesen von SPI1BUF
die Übertragung. Mach die Zeile weg und ändere die Schleife:
for(i=0; i<16; i++){
while (!SPI1STATbits.SPIRBF) set_bit(PORTA,0) ; //setze led0
clear_bit(PORTA,0); //lösche led0
SPI1[i] = SPI1BUF;
}
Da schaust du jetzt erst mal ob das so geht.
Ansonsten kann es aufgrund deines Hauptprogrammes
durchaus sein, das die Übertragung schon fast durch ist
bevor du überhaupt in SPI1Service() springst.
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.