Hallo Leute, Ich versuche mich im Moment mit der SPI Schnittstelle anzufreunden. Ich bin ein absoluter Beginner. Absolut ist in dem Fall noch milde ausgedrückt. Das Board ist ein DEMO9S08AW60 von freescale. Es soll als Master später fungieren. SPI1BR = 0x35; SPI1C1 = 0b10100000; SPI1C2 = 0x00; Nach diesen Einstellungen müsste doch eigentlich ein Takt über die SCK Leitung gehen. Jetzt habe ich das Oszi angeschlossen, doch ich sehe nur ein stark schwankende Kurve. Was ist hier falsch?
Jan R. schrieb: > doch ich sehe nur > ein stark schwankende Kurve. Welchen Takt hast du eingestellt? Wie schnell ist dein Oszi?
Laut den Teiler Tabellen sollten es 80KHz sein, die ich eingestellt habe. Am Oszi wird neben der Kurve eine Zahl angezeigt. Die ist bis bis 2,5KHz aber schwankt viel zu stark. Jetzt kommen nur noch angezeigte Werte und keine Kurve mehr... Vom Gedankengang her ist es aber richtig, dass ich etwas messen müsste können?
50hz schwankende kurve??? ggf pins nicht richtig konfiguriert (falls das bei dem controller geht)? 73
Kannst du vielleicht mal ein Bild von den Oszi-Einstellungen hier reinstellen? Dann könnte man bewerten ob es evtl. daran liegt dass du nichts siehst. Achso, ein paar mehr Infos zum Oszi wären auch nicht schlecht...
Es geht keine Ahnung wieso.... Habe das hier: SPI1C1 = 0b10100000; SPI1C2 = 0x00; in das hier geändert: SPI1C1 = 0x50; SPI1C2 = 0x00; eigentlich dachte ich, dass die Bits im Control Register richtig gesetzt waren. Plötzlich keine schwankende Kurve mehr und schöne passende Zahlen. Nun mal eine allgemeine Verständnisangelegenheit zu SPI. Man unterscheidet bei der Kommunikation via SPI Schnittstelle zwischen einem Master und mehreren möglichen Slaves. Diese können dann verschieden angeordnet sein (Daisy-Chain oder sternförmig). Um eine Verbindung bzw. Kommunikation zu ermöglichen, muss zuerst der Master konfiguriert werden. Dazu werden in den Controlregistern die passenden Bits gesetzt, als auch der Taktteiler angegeben. SPI1BR = 0x35; SPI1C1 = 0x50; SPI1C2 = 0x00; Nun muss der Slave konfiguriert werden. Dazu müssen im Control Register wieder die passenden Bits gesetzt werden. Das Master-Bit darf nicht gesetzt werden. Wenn es jetzt zur Kommunikation bzw. Datenaustausch kommt, muss beachtet werden, dass dieser immer synchron stattfindet, d.h. es werden IMMER gleichzeitig Daten gesendet und Empfangen. Außerdem muss beachtet werden, dass die nötigen Statusflags richtig sind und es nicht zu einem Überlauf eines Buffers (transmission oder read) kommt. void SendData (unsigned char data) { do{ spi_status = SPI1S; } while( (spi_status) == 0); SPI1D = data; } Wo befinden sich die Daten, die vom Slave dann zum Master gesendet wurden. Auch im Data register? Oder in einem Buffer? Könnt ihr einfach mal drauf schauen, ob ich es richtig verstanden habe? Vielen Dank!
Jan R. schrieb: > Habe das hier: > > SPI1C1 = 0b10100000; > SPI1C2 = 0x00; > > in das hier geändert: > > SPI1C1 = 0x50; > SPI1C2 = 0x00; 0b10100000 = 0xa0 != 0x50 = 0b01010000
Ah dann habe ich mich da mit einer 0 vertan gehabt. Sehr gut, ich schaue mir gleich nochmal die einzelnen Bits in dem Control Register an, welches dann falsch war.
Jan R. schrieb: > Ah dann habe ich mich da mit einer 0 vertan gehabt. Sehr gut, ich schaue > mir gleich nochmal die einzelnen Bits in dem Control Register an, > welches dann falsch war. Deswegen schreibt man das auch nicht so: 0b0010000. Weil bei 0b000100000 niemand auf einen Blick sieht ob es 7, 8 oder 9 Bit sind. Hexadezimale Schreibweise ist zwar eindeutig lesbar, aber welche Bits da gesetzt werden, ist auch nicht sofort erkennbar und bei der Umrechnung sehr fehleranfällig. Ganz zu schweigen von den Witzbolden, die das dezimal schreiben. Deswegen benutzt man die Schreibweise mit den Bitnamen: SPCR |= (1 << SPE) | (1 << MSTR); Das ist jetzt AVR. Aber zu deinem Compiler werden wohl auch Header gehören, die das unterstützen. Sollte das nicht so sein, kannst du dir sowas selber schreiben. Ist natürlich eine Mordsarbeit. Aber die Open-Source-Leute machen sich die Arbeit ja auch für die Allgemeinheit. Als kleine Verbesserung könntest du aber zumindest mit
1 | #define Bit7 7
|
2 | #define Bit6 6
|
3 | ...
|
4 | #define Bit0 0
|
etwas mehr Übersicht erlangen. Dann musst du nur im Datenblatt gucken, an welcher Position im Register das betreffende Bit steht: Statt SPI1C1 = 0x50; schreibst du dann SPI1C1 = (1 << Bit6) | (1 << Bit4); Kannst natürlich auch "SPI1C1 = (1 << 6) | (1 << 4);" schreiben. Das kommt aufs gleiche raus. Aber das mit Bitx zu schreiben, finde ich immer noch übersichtlicher. Du hast ja selbst gesehen, daß man sich mit wegen einem verschobenen Bit dumm und dämlich suchen kann. Und keine Angst, da wird im Controller nichts geschoben und verodert. Das rechnet der Compiler vorher aus. mfg.
Vielen Dank für die Antwort bezgl. der besseren Schreibweise. Werde ich gleich mal schauen, ob freescale etwas bereitstellt. Könnte noch jemand zu meinem Text bzgl. SPI Stellung nehmen, inwiefern ich es verstanden habe? Wäre super nett! Muss es hier so heißen: SPI1C1 = (1 << Bit6) | (1 << Bit4); oder so: SPI1C1 |= (1 << Bit6) | (1 << Bit4); Ich würde sagen Letzteres, da die Oder-Verknüpfung angewendet werden muss.
Jan R. schrieb: > Vielen Dank für die Antwort bezgl. der besseren Schreibweise. > Werde ich gleich mal schauen, ob freescale etwas bereitstellt. > Könnte noch jemand zu meinem Text bzgl. SPI Stellung nehmen, inwiefern > ich es verstanden habe? > Wäre super nett! Ohne deinen Controller zu kennen. Aber Motorola bzw. Freescale kochen auch nur mit Wasser. Bei allen mir bekannten SPIs ist so, daß es 1 Datenregister gibt. Das sind tatsächlich natürlich zwei, aber vom Zugriff her ist es eins. Beim Master schreibt man Daten rein und die SPI-"Mechanik" schiebt diese Bit für Bit raus. Zur gleichen Zeit sorgt der Takt dafür, daß das, was im Datenregister(Senden) des Slave steht, Bit für Bit ausgelesen wird und im Datenregister(Empfangen) des Master landet. > Muss es hier so heißen: > SPI1C1 = (1 << Bit6) | (1 << Bit4); > > oder so: > > SPI1C1 |= (1 << Bit6) | (1 << Bit4); > > Ich würde sagen Letzteres, da die Oder-Verknüpfung angewendet werden > muss. Nach Reset sollte das Register 0 sein. Damit würde die zweite Version das Register richtig beschreiben. Mit der ersten Version stellst du allerdings sicher, daß in jedem Falle genau das drinsteht, was du haben willst. Egal an welcher Stelle im Programm du das machst oder welcher Müll da evtl. vorher drinstand. Bei der Initialisierung des Registers benutzt man die erste, will man in einem gesetzten Register etwas ändern, nimmt man die zweite Version. mfg.
Ok gut vielen Dank. Mein Controller ist der MC9S08AW60 von freescale. Ich denke so in der Art hatte ich es auch verstanden. Komliziert wird es dann nur, wenn interruptgesteuert,d.h. immer wenn der transmission buffer leer ist, dass dann automatisch ein Interrupt ausgelöst wird und so der nächste Datensatz geschickt wird. Hier bei einem Beispiel: do { spi_status = SPI1S; } while( (spi_status&0x20) == 0); SPI1D = 0x3C; Wieso wurde noch geprüft, ob 0x20 auch gleich 0 ist? Im forum hier habe ich es schon mal gesehen, kann es mir nur nicht erklären? Ist das eventuell eine controllerspezifische Geschichte?
Jan R. schrieb: > Hier bei einem Beispiel: > > do { > spi_status = SPI1S; > } > while( (spi_status&0x20) == 0); > SPI1D = 0x3C; > > Wieso wurde noch geprüft, ob 0x20 auch gleich 0 ist? > Im forum hier habe ich es schon mal gesehen, kann es mir nur nicht > erklären? > Ist das eventuell eine controllerspezifische Geschichte? 0x20 kann niemals 0 sein. Das ist mathematischer Unsinn. Hier "while( (spi_status&0x20) == 0);" wird mit der UND-Verknüpfung ein Bit ausmaskiert. Da kommt auch wieder die Schreibweise ins Spiel: while((spi_status & (1 << Bit5)) == 0); Allerdings macht man man das nicht so aufwendig: > do { > spi_status = SPI1S; > } > while( (spi_status&0x20) == 0); while (!(SPI1S & (1 << Bit5)); tut das gleiche und jeder sieht auf einen Blick, daß hier gewartet wird, solange Bit5 des SPI1S-Registers 0 ist. Bit5 wird am Anfang der Übertragung auf 0 gesetzt und am Ende wieder auf 1. Mit der Abfrage und dem damit verbundenen Warten verhindert man, daß das Datenbyte währenddessen überschrieben wird. mfg.
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.