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