Forum: HF, Funk und Felder RFM12 SPI Funktion


von Michael K. (schmid111)


Lesenswert?

Hallo.

Ich habe mit der Hilfe des Beitrags "Beispielprogramm für RFM12 433MHz 
Funk-Module" (Link:Beitrag "Beispielprogramm für RFM12 433MHz Funk-Module" 
Funkübertragung zwischen 2 selbstgebauten Platinen hergestellt. Das 
Programm welches im Beitrag enthalten ist habe ich auf 868MHz 
umgeschrieben und habe dabei noch ein paar Einstellungen angepasst. Es 
werden jetz daten von einer Platine auf eine andere Übertragen und von 
dieser mittels serieller Schnittstelle auf ein Raspberry Pi übertragen.

Das Programm ist weitgehend logisch und mittels Datenblatt können nette 
"adjustments" gemacht werden nur eine Funktion ist mir nicht ganz klar.


Die Funktion:"rf12_trans"

unsigned short rf12_trans(unsigned short wert)
{  unsigned short werti=0;
  unsigned char i;

cbi(RF_PORT, CS);
for (i=0; i<16; i++)
{if (wert&32768)
sbi(RF_PORT, SDI);
else
cbi(RF_PORT, SDI);
werti<<=1;
if (RF_PIN&(1<<SDO))
    werti|=1;
    sbi(RF_PORT, SCK);
    wert<<=1;
    _delay_us(0.3);
    cbi(RF_PORT, SCK);
  }
  sbi(RF_PORT, CS);
  return werti;
}


Mir ist bewusst das diese Funktion für den Datenverkehr zwischen 
Mikrocontroller und Funkmodul verantwortlich ist, da beide mittels SPI 
kommunizieren.

Die SPI Anschlüsse verstehe ich so:

CS bzw. SS: Slave Select, wenn dieser von High auf LOW geht startet die 
Datenübertragung und das Modul weiß das der Mikrocontroller nun Befehle 
erteilt

SDI u. SDO: das sind die Datenleitungen für den Datentransfer zwischen 
Modul und Controller

SCK: das Taktsignal für die SPI-Schnittstelle


Bis zum Start der Kommunikation (CS auf LOW) ist mir alles klar nur ab 
der For-Schleife (in welcher anscheinend der Befehl z.B. 0x0000 Bit für 
Bit übertragen werden soll) bin ich ziemlich ratlos. Besonders aus den 
ganzen Abfragen und setzen der Datenleitungen werd ich nicht schlau.

Falls mir irgendjemand diesen Teil erklären könnte oder weiß wo ich 
INFOS dazu herbekommen könnte wäre das einfach nur super.^^


MFG Schmid111

von Felix P. (fixxl)


Lesenswert?

Bei SPI werden "gleichzeitig" Daten vom Master zum Slave und vom Slave 
zum Master übertragen. Master ist in deinem Fall der Controller, Slave 
das Funkmodul, SDI führt die Daten vom Master zum Slave, SDO die vom 
Slave zum Master. Die Zeitpunkte der Datenübertragung bestimmt das 
SCK-Signal.

In der for-Schleife werden 16 Bit in beide Richtungen übertragen, der 
vom Master zum Slave zu übertragende Wert wird der Funktion als Argument 
übergeben. Der kann 0x0000 sein wie von dir beschrieben, muss aber 
nicht.

Was nun passiert:
1
if (wert&32768) sbi(RF_PORT, SDI);
2
else cbi(RF_PORT, SDI);
Das höchstwertige Bit des Übergabewerts "wert" wird überprüft: Ist er 1, 
wird der Pin SDI auf high gezogen, ist er 0, dann geht der Pin auf low.
1
werti<<=1;
Die Variable zum Einlesen des vom Slave zum Master übertragenen Werts 
wird um eins nach links geschoben. Im ersten Durchlauf ist das noch 
scheinbar sinnlos, später hat es den Effekt, dass man die bisher 
gelesenen Werte um eins nach links schiebt, um am hinteren Ende Platz 
für einen neuen zu machen. Den holt man sich im nächsten Schritt:
1
if (RF_PIN&(1<<SDO)) werti|=1;
Der Pinzustand von SDO wird überprüft. Ist er auf high, wird eine 1 ins 
niedrigste Bit von werti geschrieben. Der Fall, dass der Pin low ist, 
wird nicht explizit behandelt, da bleibt das unterste Bit von werti 
einfach 0.
1
sbi(RF_PORT, SCK);
Durch setzen des Clock-Ausgangs auf high, wird der Wert von SDI ans 
Funkmodul übertragen.
1
wert<<=1;
Nachdem das höchstwertige Bit übertragen worden ist, braucht man es 
nicht mehr. Man schiebt die Bits von wert daher um eins nach links, so 
dass nun das vorher zweithöchste Bit zum höchsten wird (das wird dann im 
nächsten Schleifendurchlauf geprüft!).
1
_delay_us(0.3);
Durch diese Anweisung wird sichergestellt, dass der SPI-Takt nicht 
schneller ist als das Funkmodul erlaubt. Man wartet einfach 300ns.
1
cbi(RF_PORT, SCK);
Anschließend wird der Clock-Ausgang wieder zu 0. Man hat ein Bit 
gesendet und ein Bit empfangen, der nächste Durchgang kann beginnen.

: Bearbeitet durch User
von Michael K. (schmid111)


Lesenswert?

Vielen herzlichen Dank.

Hat mir wirklich sehr geholfen das ganze komplett zu verstehen.
Werde in Zukunft noch mehr damit experimentieren.

:)

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.