Hi zusammen, ich versuche mit einem ATMega328P Daten per SPI an einen Motortreiber zu senden. Leider erfolglos. Der Mikrocontroller denkt nicht mal dran, Daten zu senden. Am Oszi sind keine Daten erkennbar, am MoSI Pin. Im Prinzip möchte ich folgende Daten senden: char systembyte1 = 0b11001010; char systembyte2 = 0b11000001; char motorbyte1 = 0b11011000; char motorbyte2 = 0b00000010; Ich aktiviere die SPI Schnittstelle und Slave Select: // Set MOSI, SCK as Output DDRB|=(1<<PB5)|(1<<PB3); DDRC |= (1 << PC1); //SS AUsgang SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0); sei(); Anschließend will ich die Daten aussenden: while (1) { PORTC &=~(1<<PC1); //SS auf low SPDR = systembyte1; //Wert i schreiben while(!(SPSR &(1<<SPIF))); //Warten bis alles übertragen ist SPDR = systembyte2; //Wert i schreiben while(!(SPSR &(1<<SPIF))); //Warten bis alles übertragen ist PORTC |= (1 << PC1); //SS High _delay_ms(100); PORTC &=~(1<<PC1); //SS auf low SPDR = motorbyte1; //Wert i schreiben while(!(SPSR &(1<<SPIF))); //Warten bis alles übertragen ist SPDR = motorbyte2; //Wert i schreiben while(!(SPSR &(1<<SPIF))); //Warten bis alles übertragen ist PORTC |= (1 << PC1); //SS High Leider finde ich nicht den Fehler. Es müsste doch eigentlich funktionieren? Mit dem Oszi müsste ich doch wenigstens das SCK Signal sehen? Jemand eine Idee? Danke im Voraus
Vielleicht liegt es daran: "If /SS is configured as an input, it must be held high to ensure Master SPI operation." /SS liegt auf B2.
Pin B2 ist bei mir nicht belegt. Sollte ich dann PB2 als Output konfigurieren und auch High setzen?
Dabla sagt: "When the SPI is configured as a Slave, the Slave Select (SS) pin is always input. When SS is held low, the SPI is activated, and MISO becomes an output if configured so by the user. All other pins are inputs. When SS is driven high, all pins are inputs except MISO which can be user configured as an output, and the SPI is passive, which means that it will not receive incoming data. Note that the SPI logic will be reset once the SS pin is driven high. The SS pin is useful for packet/byte synchronization to keep the Slave bit counter synchronous with the master clock generator. When the SS pin is driven high, the SPI Slave will immediately reset the send and receive logic, and drop any partially received data in the Shift Register. Master Mode When the SPI is configured as a Master (MSTR in SPCR is set), the user can determine the direction of the SS pin. SPI Control Register – SPCR 2486Z–AVR–02/11 If SS is configured as an output, the pin is a general output pin which does not affect the SPI system. Typically, the pin will be driving the SS pin of the SPI Slave. If SS is configured as an input, it must be held high to ensure Master SPI operation. If the SS pin is driven low by peripheral circuitry when the SPI is configured as a Master with the SS pin defined as an input, the SPI system interprets this as another Master selecting the SPI as a Slave and starting to send data to it. To avoid bus contention, the SPI system takes the following actions: 1.The MSTR bit in SPCR is cleared and the SPI system becomes a Slave. As a result of the SPI becoming a Slave, the MOSI and SCK pins become inputs 2.The SPIF Flag in SPSR is set, and if the SPI interrupt is enabled, and the I-bit in SREG is set, the interrupt routine will be executed Thus, when interrupt-driven SPI transmission is used in Master mode, and there exists a possi- bility that SS is driven low, the interrupt should always check that the MSTR bit is still set. If the MSTR bit has been cleared by a Slave Select, it must be set by the user to re-enable SPI Master mode." MfG
S. Landolt schrieb: > Ja, d.h. entweder - oder; beides kann auch nicht schaden. Hab ich gemacht, leider kein Fortschritt.
Hallo,
versuch mal bei SPI-Init ein leeres Byte zu senden, um SPI-Logik zu
aktivieren.
>> Mit dem Oszi müsste ich doch wenigstens das SCK Signal sehen?
Nicht unbedingt. Kann sein, du siehst nur diese Pause:
1 | _delay_ms(100); |
Um SCK mit Oszi zu sehen, versuch mal permanent zu senden. MfG
:
Bearbeitet durch User
> Hab ich gemacht, leider kein Fortschritt.
Also ich sehe bei mir sowohl SCK als auch MOSI.
Wenn ich den µC programmiere, dann sehe ich SCK. Sobald er dann in seine eigene Programmschleife reinläuft sehe ich nur alle 10ms ein kleinen Ausschlag auf der SCK Leitung. Verstehe nicht, warum er nichts sendet. Habe ich eventuell irgendeine Konfiguration vergessen? Oder ist der Code oben vollständig?
Bolot J. schrieb: > S. Landolt schrieb: >> Ja, d.h. entweder - oder; beides kann auch nicht schaden. > > Hab ich gemacht, leider kein Fortschritt. Setze mal den SS Pin PB2 hoch. Wenn ich mich nicht irre, ist bei Dir der SS Pin nicht explizit gesetzt. Ist also bei Default ein Eingang. Wenn dieser pin dann auch noch LOW ist intern, dann ist der SPI Port im SLAVE Modus und gibt nichts aus. (Siehe vorherigen Beitrag von Christian) Zur Vorsicht würde ich raten den PB2(SS-) als OUTPUT zu konfigurieren. Dann sollte das nichts mehr ausmachen. (Bei meinen Sachen funktioniert SPI so immer) Also kann der SS Pin bei Dir nicht als GP Input Pin verwendet werden solange SPI aktiv ist und sollte zumindest auf HIGH sein.
> sehe ich nur alle 10ms ein kleinen Ausschlag auf der SCK Leitung.
Das ist erstaunlich, bei "_delay_ms(100)"; mal diese Zeile
auskommentieren.
Bolot J. schrieb: > Verstehe nicht, warum er nichts sendet. Habe ich eventuell irgendeine > Konfiguration vergessen? Oder ist der Code oben vollständig? Tue mal das: // Set MOSI, SCK, SS as Output DDRB|=(1<<PB5)|(1<<PB3)|(1<<PB2);
Gerhard O. schrieb: > Bolot J. schrieb: >> Verstehe nicht, warum er nichts sendet. Habe ich eventuell irgendeine >> Konfiguration vergessen? Oder ist der Code oben vollständig? > > Tue mal das: > > // Set MOSI, SCK, SS as Output > DDRB|=(1<<PB5)|(1<<PB3)|(1<<PB2); Hab ich gesetzt. Und PB2 auf high. Allerdings das gleiche Problem. Ist mein Datentyp als Char korrekt? Kann ich die Daten auch so im 0bxxxxxy Format im Char speichern, sodass er mir später die einzelnen Bits sendet? Oder liegt vielleicht hier der Fehler?
S. Landolt schrieb: > Läuft bei mir! Danke. Dann suche ich den Fehler weiter. Wenigstens weiß ich, dass es nicht am Code liegt.
Arduinator schrieb: > Bolot J. schrieb: >> Oder liegt vielleicht hier der Fehler? > > SPI Fuse enabled/disabled? Prüfe ich nach. Die Fuse muss enabled sein, richtig?
Mal dies hier ausprobieren, selbst wenn SCK bzw. MOSI nicht zu sehen ist, so sollte doch das Schalten auf C1 und C5 vorhanden sein. Wird für den richtigen Controller, ATmega328, übersetzt?
>> Tue mal das: >> // Set MOSI, SCK, SS as Output >> DDRB|=(1<<PB5)|(1<<PB3)|(1<<PB2); Bolot J. schrieb: > Hab ich gesetzt. Und PB2 auf high. Jetzt ist der /SS Pin als Ausgang konfiguriert. Dann muss er LOW sein!
> Jetzt ist der /SS Pin als Ausgang konfiguriert. Dann muss er LOW sein!
Ohne Scherz jetzt?
S. Landolt schrieb: >> Jetzt ist der /SS Pin als Ausgang konfiguriert. Dann muss er LOW > sein! > > Ohne Scherz jetzt? Sicher doch, sonst ist der Slave nicht selektiert und hört nicht zu, was der Mikrocontroller ihm sendet.
Soweit ist Bolot J. doch noch gar nicht, er sieht nicht einmal Aktivität auf SCK oder MOSI.
S. Landolt schrieb: > Mal dies hier ausprobieren, selbst wenn SCK bzw. MOSI nicht zu sehen > ist, so sollte doch das Schalten auf C1 und C5 vorhanden sein. > > Wird für den richtigen Controller, ATmega328, übersetzt? Ich Probier das mal. Der richtige Controller ist in Atmel Studio ausgewählt. Danke für die zahlreichen Hinweise.
So, SPI funktioniert nun. vielen Dank für die Hilfe. Eine Frage hätte ich noch, der Slave benötigt SCK=1 wenn ich SS setzen will. Kann ich SCK manuell auf 1 setzen um SS auf High und Low zu ändern?
S. Landolt schrieb: > Übrigens hängt bei ihm /SS für den Motortreiber auf C1. Das interessiert aber die SPI-Hardware im ATmega nicht. Die guckt auf PB2.
> Das interessiert aber ... Das interessiert aber den Motortreiber nicht, denn der zitierte Text bezog sich auf > Sicher doch, sonst ist der Slave nicht selektiert und hört > nicht zu, was der Mikrocontroller ihm sendet. wie sich unschwer hätte nachlesen lassen.
Beitrag #5736633 wurde vom Autor gelöscht.
Bolot J. schrieb: > So, SPI funktioniert nun. vielen Dank für die Hilfe. > > Eine Frage hätte ich noch, der Slave benötigt SCK=1 wenn ich SS setzen > will. > Kann ich SCK manuell auf 1 setzen um SS auf High und Low zu ändern? Das kannst Du vielleicht im SPI SRF einstellen, so dass es passt. Manchmal sind Peripherie Serial ICs eigentlich mehr für Bitbanging gedacht. Guck mal hier nach: https://www.sparkfun.com/datasheets/Components/SMD/ATMega328.pdf DaBa S173 Kapitel 16.5 Unter SPCR (SPI Kontroll Register) für Bits CPOL und CPHA Wenn das mit deinem IC kompatibel ist, solltest Du damit klarkommen. Sonst bleibt nur noch Bit-banging übrig. Allerdings hast Du damit volle Kontrolle über die Busverbindung und ist nicht kompliziert.
:
Bearbeitet durch User
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.