Hallo an alle! Habe gestern versucht, einen SPI Slave mit dem ATmega8 anzusteuern(als Master konfiguriert). Dachte, dass sei eine ganz einfache Übung, zumal auch im Dtaenblatt Codeexamples vorhanden sind. Habe das genau so abgekupfert, der c ist als master konfiguriert, SPI ist enabled. Ich ziehe also den SS pin "manuell" auf "Low" (weil µc ja im master mode) und schiebe dann drei Bytes in das SPI Datenregister. Danach ziehe ich die SS Leitung wieder auf "high". Dummerweise passiert auf meiner SCK leitung überhaupt nichts (Immer "high"). Habe aber die Pins MOSI, SCK und SS als Ausgang definiert. Mir fällt einfach keine Fehlerquelle mehr ein. hat jemand einen Tipp, was ich da noch übersehen könnte? Danke ;-)
OK, hab leider nun leider den Code nicht bei der Hand aber die paar Zeilen habe ich glaub ich noch im Kopf(hoffentlich ;-) ) Sieht etwas so aus: void writeFrame(char *frame) { PORTB &= ~(1<<PB2); for(i=0;i<3;i++) { SPDR = *frame; while(!(SPSR & (1<<SPIF))); frame++; } PORTB |= (1<<PB2); } Im void main ist dann der Aufruf: char frame[3]; frame[0] = 0x02; frame[1] = 0x06; frame[2] = 0x55; //MOSI, SS and SCK as Output DDRB = (1<<PB2) | (1<<PB3) | (1<<PB5); //Enable SPI SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0) | (1<<DORD); writeFrame(frame); Hoffe, hab nun aus dem Kopf heraus nichts vergessen....
@ Bernhard (Gast) >Dachte, dass sei eine ganz einfache Übung, zumal auch im Dtaenblatt >Codeexamples vorhanden sind. AVR-Tutorial: Schieberegister >OK, hab leider nun leider den Code nicht bei der Hand aber die paar >Zeilen habe ich glaub ich noch im Kopf(hoffentlich ;-) ) Sowas kannst du dir sparen. Es kommt da auf jedes Detail an. Entweder originalen Quelltext oder gar nichts. MFG Falk
Hast du deine Interrupts eingeschaltet (im SREG)???
1 | while(!(SPSR & (1<<SPIF))); |
Falls du das Bit SPIF im SPI-Comtrollregister ließt, ohne den Interrupt einzuschalten, bis du in einer Edenlosschleife !?!
Im Gegenteil: wenn du den Interrupt aktivierst (SPIE und sei()), landest du wahrscheinlich in einer Endlosschleife, weil das flag sofort von der ISR gelöscht wird ;) sry for klugscheißing -Jörg
Hallo, Der Code sollte OK sein, das Datenblatt von Atmel ist da etwas bescheiden geschrieben. Zitat von Dir: "Ich ziehe also den SS pin "manuell" auf "Low" (weil µc ja im master mode) und schiebe dann drei Bytes in das SPI Datenregister." Schau dir mal den Inhalt vom SPSR Register an - ist das WCOL bit gesetzt wenn du versuchst zu schreiben? Habe vor ein paar Tagen dasselbe gehabt. Atmel als Master, SD-Card als Slave, SS Pin als Chip select. Das geht mal definitiv NICHT! Der SS-PIN darf im Mastermodus NICHT low sein während der Master senden will. SS Pin Low bedeutet ein anderer Master versucht zu senden. Nehm einfach nen anderen Pin und sorge dafür das SS High ist und bleibt { DDRB|=(1<<SS-PIN) PORTB|=(1<<SS-PIN) } Das sollte helfen Gruß ---=DIAN=---
---=DIAN=--- wrote: > Der SS-PIN darf im Mastermodus NICHT low sein während der Master senden > will. Solange er als Ausgang konfiguriert ist, ist das völlig egal. Er darf nur nicht Eingang und Low sein.
Hallo! So, der Vollständigkeit halber nun hier mein ganzes AVRStudio project im anhang! Vielleicht kommt da ja noch ein Fehler zu Tage ;-) Bitte um eure Hilfe. Lg, Bernhard
Ok, ich hab zwar nen Mega32, aber da sollte es wohl gleich sein. Komischerweise klappt bei DDRB|=(1<<SS) PORTB|=(1<<SS) die SPI Kommunikation und bei DDRB|=(1<<SS) PORTB&=~(1<<SS) eben nicht mehr, dann bekomme ich WCOL ohne Ende. Hab's ja selbst probiert, das Tutorial im Datenblatt funzt nicht, wenn man SS auf low zieht, weiß ich warum.... ---=DIAN=---
Gut, aber wenn ich das datenblatt richtig verstanden haben, muss sich der Coder selbst um das chipsselect signal kümmern, wenn der avr im spi master modus arbeitet. Aber das man den eigentlich dazu gedachten SS pin nicht benutzen kann, gibt es eigentlich nicht (sorry, ich weiß du sagtest, du hast es ausprobiert). Aber da ist dann doch irgendetwas faul oder? Grüße
Berhard wrote: > Gut, aber wenn ich das datenblatt richtig verstanden haben, muss sich > der Coder selbst um das chipsselect signal kümmern, wenn der avr im spi > master modus arbeitet. Richtig. > Aber das man den eigentlich dazu gedachten SS pin nicht benutzen kann, > gibt es eigentlich nicht (sorry, ich weiß du sagtest, du hast es > ausprobiert). Nein, der Pin ist nicht dafür gedacht. SS\ ist immer ein Eingangssignal, über das der jeweilige Slave vom Master aktiviert wird. Der Master selbst hat kein Slave Select, weil er eben kein Slave ist. Er muss aber über entsprechende Datenleitungen den Slave Select-Eingang des Slaves, mit dem er sprechen will, ansteuern. Da der Master selbst kein Slave Select hat, wird der Pin im Master-Modus auch eigentlich nicht verwendet. Und (lt. Datenblatt) ist er auch, wenn er als Ausgang konfiguriert ist, als allgemeiner Ausgang nutzbar (ob man damit jetzt den Slave Select eines der angeschlossenen Slaves ansteuert, bleibt dem Nutzer überlassen). Nur wenn SS\ als Eingang konfiguriert ist, hat er auch im Master-Modus eine Funktion, nämlich den Master in den Slave-Modus zu schalten, wenn der Pin auf Low gezogen wird. Dies soll den Aufbau eines "Pseudo-Multi-Master-Systems" ermöglichen. "Pseudo" deshalb, weil es bei SPI immer nur einen Master geben kann und deshalb alle Master, die von einem anderen als Master konfigurierten Teilnehmer angesprochen werden, sofort in den Slave-Modus schalten müssen. (Ist wie bei Highlander: Es kann nur einen geben...). > Aber da ist dann doch irgendetwas faul oder? Wenn sich das so verhält, wie ---=DIAN=--- es oben beschrieben hat, dann ist tatsächlich etwas faul. Es besteht dann zumindest ein Widerspruch zwischen Realität und Dokumentation (Datenblatt)...
Hy! Habe dieses Verhalten noch nicht probiert(besser gesagt, keine Gelegenheit dazu). Ich habe bei mir zuhause kein Oszilloskop oder ähnliches zur Verfügung und ohne allem tu ich mir etwas schwer, Diagnosen zu stelllen. Eigentlich sollte ich die SPI Ansteuerung heute schon fertig haben, aber was soll man machen ;-) Hab mich nur gewundert, warum der Slave nicht antwortet, bis ich heute morgen gesehen habe, dass da ja gar nichts rauskommt aus meinem AVR :-P Trotzem: Was mir noch fehlt , ist herauszufinden, was der Fehler in meinem Programm ist (Programm ist für diese paar Zeilen eigentlich übertrieben,...) Johannes, hast du einen Blick auf den Code geworfen und ist dir etwas aufgefallen? Kann durchaus sein, dass ein ganz dummer Fehler dahintersteckt, bin quais Anfänger :-) Danke. Lg, Bernhard
@ Berhard (Gast) >Hab mich nur gewundert, warum der Slave nicht antwortet, bis ich heute >morgen gesehen habe, dass da ja gar nichts rauskommt aus meinem AVR :-P Wie hast du das ohne Oszi gesehen? >Kann durchaus sein, dass ein ganz dummer Fehler dahintersteckt, bin >quais Anfänger :-) Dein Programm sieht erstmal gut aus. Ich kann keinen Fehler entdecken. Wenn gleich man einige Sachen takisch besser machen kann/sollte. Die Defines für die Register des SPI-Moduls sind Quark. Sinnvoll sind eher defines für die Pins des SPI-Moduls, weil die auf jedem AVR anders liegen. Siehe AVR-Tutorial: Schieberegister . Und wenn eine Funktion SPIWriteByte() heisst, dann sollte sie auch das machen was der Name sagt, nämliche EIN Byte senden. Du sendest aber mehrere. Die Anzahl sollte man als Parameter übergeben und nicht fest kodieren. Das ist nicht gut, da entstehen ggf. zu grosse Rundungsfehler #define UBBR_VAL F_CPU/16/BAUD-1 besser so wie hier http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#UART_initialisieren Ausserdem sind deine Headerfiles ein ziemliches Kauderwelsch, es werden verschiedene Files mehrfach eingebunden, das kann auch mal daneben gehen, z.B. mit globalen Variablen. MFG Falk
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.