Forum: Mikrocontroller und Digitale Elektronik SPI Verständnisproblem


von Willi will´s Wissen (Gast)


Lesenswert?

Hallo zusammen,

ich muss über die SPI-Schnittstelle das Protokoll eines GPS mit einem 
Mikrocontroller (ATMEGA328) auslesen und auswerten. Ich hab mich jetzt 
mal eingelesen und komm´ nicht so recht vorwärts. Mein GPS wäre also im 
Masterbetrieb der Sender-Slave und mein Controller der Empfänger-Slave. 
Jetzt ist es ja so, dass der Sender- bzw. Empfänger-Slave nicht 
automatisch durch die Schnittstelle freigegeben wird, sondern mit einem 
besonderen Befehl über den als Ausgang programmierten Anschluss SS.

Die Übertragung beginnt, wie ich gelesen habe, mit dem Schreiben eines 
Bytes in das Datenregister SPDR durch eine Art Ausgabebefehl...

Für den Empfang eines Bytes vom Sender muss dann wiederum ein beliebiges 
Startbyte in SPDR geschrieben werden um die Übertragung am MISO zu 
starten. Ich muss also das Senden des GPS durch ein Setzen eines 
beliebigen Bytes initialisieren.

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;
}

Ich steig nicht durch, zum Haare raufen...Hat mir jemand einen guten 
Literatur Tipp oder ähnliches?!
Bin für jeden Hinweis dankbar!
Gruß,
Willi

von Thomas E. (thomase)


Lesenswert?

Willi will´s Wissen schrieb:
> mal eingelesen und komm´ nicht so recht vorwärts. Mein GPS wäre also im
>
> Masterbetrieb der Sender-Slave und mein Controller der Empfänger-Slave.
>
> Jetzt ist es ja so, dass der Sender- bzw. Empfänger-Slave nicht
>
> automatisch durch die Schnittstelle freigegeben wird, sondern mit einem
>
> besonderen Befehl über den als Ausgang programmierten Anschluss SS.

Da hast du jetzt ja echt einen Knoten im Kopf.

Vergiss jetzt mal MISO und MOSI. Hast du noch nie gehört.

Atmega ist Master:
Pin 17 ist Output (Master Output) >> Device Input
Pin 18 ist Input (Master Input)   << Device Output
PIN 19 ist Clock Output           >> Device Clock Input

Atmega ist Slave:
Pin 17 ist Input (Slave Input)    << Device Output
Pin 18 ist Output (Slave Output)  >> Device Input
PIN 19 ist Clock Input            << Device Clock Output


Das ist alles. Und Master ist der, der den Taktstock schwingt.
Und meistens sind die angeschlossenen Devices die doofen, als Slave.

mfg.

von Peter D. (pdiener) Benutzerseite


Lesenswert?

>Ich steig nicht durch, zum Haare raufen...Hat mir jemand einen guten
>Literatur Tipp oder ähnliches?!

SPI ist ganz einfach. Es gibt einen Master und mindestens einen Slave.
Über eine Chipselect-Leitung (oder Slave-Select (SS)) wird ausgewählt, 
mir welchem Slave der Master gerade kommuniziert.

Bei jedem Übertragungzyklus wird gleichzeitig ein Byte vom Master zum 
Slave und ein Byte vom Slave zum Master gesendet.

Die oben gezeigte Funktion SPI_MasterTransmit ignoriert einfach die 
Daten, die vom Slave zum Master übertragen werden.

So macht man das, wenn man diese Daten benötigt:

unsigned char SPI_MasterTransfer(unsigned char sendData)
{
  /* Start transmission */
  SPDR = sendData;

  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF))) {}

  return SPDR;
}

Diese Funktion kann man jetzt aufrüfen, z.B. so:

unsigned char returnvalue;

// hier richtigen Chipselect setzen
returnvalue = SPI_MasterTransfer(0x00);
// hier Chipselect wieder rücksetzen

Hier wird 0x00 an den Slave gesendet und die Antwort vom Slave in 
returnvalue geschieben.

Grüße,

Peter

von Willi will´s Wissen (Gast)


Lesenswert?

Hallo zusammen,

danke für die Antworten.

Also wie ich das jetzt verstanden habe, muss ich immer 1 Byte an den 
Slave senden, um von diesem eine Antwort bzw. meine GPS Koordinaten zu 
erhalten, Byte für Byte. Kann ich da ein beliebiges Byte verschicken, 
0xFF, 0xA7, 0xB4, etc.?

unsigned char SPI_MasterTransfer(unsigned char sendData)
{
  /* Start transmission */
  SPDR = sendData;

  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF)));

  return SPDR;
}

>> // hier richtigen Chipselect setzen
>> returnvalue = SPI_MasterTransfer(0x00);
>> // hier Chipselect wieder rücksetzen

>> Hier wird 0x00 an den Slave gesendet und die Antwort vom Slave in
>> returnvalue geschieben.

Ich versteh immer noch nocht so ganz, was es mit diesem Senden eines 
Bytes auf sich hat und was mit "richtigen Chipselect setzen"  und wieder 
zurücksetzen gemeint ist.
Der Slave Select muss im Masterbetrieb ja als Ausgang programmiert 
werden und für eine Übertragung von Slave zu Master auf Low gesetzt 
werden, oder?
Irgendwie will es noch nicht so richtig in meinen Kopf!
VG

von rainer (Gast)


Lesenswert?

Der Salve selbst kann ja keinen Takt erzeugen. Dieser ist aber nötig um 
die Daten zu übertragen. Deshalb muss der Takt vom Master erzeugt 
werden. Das macht der aber nur wenn er Daten sendet. Deshalb schickst du 
beliebige Daten (byteweise) vom Master an den Slave, wenn Du Daten vom 
Slave empfangen willst.
Im Prinzip besteht SPI aus zwei Schieberegistern (je eins bei Master und 
Slave), deren Inhalt ausgetauscht wird, sobald ein Takt anliegt.

von Willi will´s Wissen (Gast)


Angehängte Dateien:

Lesenswert?

Ah Ok,Danke für die Antwort Rainer!

Im Grunde sieht das dann also so aus....
Der Slave Select wird dann also als Ausgang programmiert. Bei Ausgang 
Low sendet er, da die SS Low-Aktiv sind. Bei Ausgang High wird die 
Übertragung beendet. Passt das soweit? Muss ich bei der Initialisierung 
außer dem hier

unsigned char SPI_MasterTransfer(unsigned char sendData)
{
  /* Start transmission */
  SPDR = sendData;

  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF))) {}

  return SPDR;
}

unsigned char returnvalue;

// hier richtigen Chipselect setzen
returnvalue = SPI_MasterTransfer(0x00);
// hier Chipselect wieder rücksetzen

sonst noch was beachten? Ich denke, eigentlich ist nur wichtig, dass man 
weiß, dass mit SS Low und High die Datenübertragung gestartet und 
beendet wird, oder?
VG

von SPIIIII (Gast)


Lesenswert?

Wie mein Vorredner schon gesagt hat, der Master sagt was abgeht und gibt 
den Takt an. Wie du oben richtig erkannt hast, sind die gesendeten Bits 
nur zum "Rausschieben" der GPS-Daten

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Der Chipselect startet an sich gar nichts. Das ist einfach eine Leitung, 
die auswählt, welcher von potentiell mehreren Slaves antworten soll, 
bzw. für wen die Daten sind.

Viele Slaves verwenden den CS zusätzlich zur Bitsynchronisation, 
deswegen muss er vor jedem Byte gesetzt werden und danach wieder 
zurückgesetzt werden, auch wenn es nur einen Slave gibt. Sonst könnte 
man bei einem Slave den CS fest auf low legen.

Die Datenübertragung wird durch Aufruf der Funktion SPI_MasterTransfer 
gestartet und komplett ausgeführt. Dabei übergibt man der Funktion das 
Byte, das vom Master zum Slave soll und bekommt das Byte als 
Rückgabewert, das der Slave an den Master gesendet hat.

Über welches GPS-Modul sprechen wir denn? Ein Link auf ein Datenblatt 
wäre hilfreich.

Grüße,

Peter

von Willi will´s Wissen (Gast)


Lesenswert?

Hi Peter,
DANKE für deine Antwort. Langsam wird das alles etwas klarer. Das 
GPS-Modul, welches ich verwende ist das ORG-1318 der Firma Origin-GPS.
http://www.origingps.com/Download.aspx?fid=48
Ok, vor und nach Übertragung eines Byte CS setzen...Werde es mir 
merken:-)
VG

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Ich habe gerade gelesen, dass das SPI am GPS nur mit 1,8 V Pegel 
funktioniert. Es wäre vielleicht besser, das über UART anzuschließen, 
denn den kann man mit bis zu 3,3 V betreiben.

Oder ist es beabsichtigt, dass die Betriebsspannung so niedrig ist? Bei 
1,8 V darf man den ATmega328 nur mit maximal 4 MHz betreiben.

Grüße,

Peter

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.