Forum: Mikrocontroller und Digitale Elektronik SPI ATMega328P Daten sende


von Bolot J. (bolot)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

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.

von Bolot J. (bolot)


Lesenswert?

Pin B2 ist bei mir nicht belegt. Sollte ich dann PB2 als Output 
konfigurieren und auch High setzen?

von S. Landolt (Gast)


Lesenswert?

Ja, d.h. entweder - oder; beides kann auch nicht schaden.

von Christian S. (roehrenvorheizer)


Lesenswert?

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

von Bolot J. (bolot)


Lesenswert?

S. Landolt schrieb:
> Ja, d.h. entweder - oder; beides kann auch nicht schaden.

Hab ich gemacht, leider kein Fortschritt.

von Maxim B. (max182)


Lesenswert?

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
von S. Landolt (Gast)


Lesenswert?

> Hab ich gemacht, leider kein Fortschritt.
Also ich sehe bei mir sowohl SCK als auch MOSI.

von Stefan E. (sternst)


Lesenswert?

Bolot J. schrieb:
> Hab ich gemacht

Wie konkret?
Vielleicht hinter der SPCR= Zeile eingefügt?

von Bolot J. (bolot)


Lesenswert?

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?

von Gerhard O. (gerhard_)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

> sehe ich nur alle 10ms ein kleinen Ausschlag auf der SCK Leitung.
Das ist erstaunlich, bei "_delay_ms(100)"; mal diese Zeile 
auskommentieren.

von Gerhard O. (gerhard_)


Lesenswert?

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);

von Bolot J. (bolot)


Lesenswert?

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?

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

Läuft bei mir!

von Arduinator (Gast)


Lesenswert?

Bolot J. schrieb:
> Oder liegt vielleicht hier der Fehler?

SPI Fuse enabled/disabled?

von Bolot J. (bolot)


Lesenswert?

S. Landolt schrieb:
> Läuft bei mir!

Danke. Dann suche ich den Fehler weiter. Wenigstens weiß ich, dass es 
nicht am Code liegt.

von Bolot J. (bolot)


Lesenswert?

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?

von S. Landolt (Gast)


Lesenswert?

Das war ein Scherz von Arduinator.

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Stefan F. (Gast)


Lesenswert?

>> 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!

von S. Landolt (Gast)


Lesenswert?

> Jetzt ist der /SS Pin als Ausgang konfiguriert. Dann muss er LOW sein!

Ohne Scherz jetzt?

von Stefan F. (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

Soweit ist Bolot J. doch noch gar nicht, er sieht nicht einmal Aktivität 
auf SCK oder MOSI.

von S. Landolt (Gast)


Lesenswert?

PS:
Übrigens hängt bei ihm /SS für den Motortreiber auf C1.

von Bolot J. (bolot)


Lesenswert?

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.

von Bolot J. (bolot)


Lesenswert?

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?

von Wolfgang (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

> 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.
von Gerhard O. (gerhard_)


Lesenswert?

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
Noch kein Account? Hier anmelden.