Forum: Mikrocontroller und Digitale Elektronik Verschiedene SPI Devices mit verschiedenen Modi (Arduino)


von Dont K. (dont_k)


Lesenswert?

Hi

Das Problem steht eigentlich schon in der Überschrift.

Ich will 3 verschiedene Devices mit 2 verschiedenen Modi betreiben (der 
Funkchip braucht einen anderen Modus.) Es geht um folgendes Arduino 
Projekt hier: Beitrag "Re: SPI Problem aufgrund von Spannungsversorgung (Arduino Uno & opt. Sensor))"
Ich benutze das normale SPI für zwei Sensoren und Mirf für den Funkchip. 
Leider greift Mirf auch auf das normale SPI zurück und ich kann deswegen 
die Modi nicht separat einstellen.

Eigentlich habe ich die Lösung schon hier gefunden:
http://www.mikrocontroller.net/articles/Serial_Peripheral_Interface
>>Es ist problemlos möglich ICs mit verschiedenen SPI-Modi an einem Bus zu 
>>betreiben, man muss nur vor dem Aktivieren des Chip Select den jeweils 
>>richtigen Modus einstellen.

Nur... Ist damit gemeint, dass ich vor jedem Zugriff den Modus umstellen 
muss? Oder gibt es eine Möglichkeit das von Anfang an zu definieren? 
(Ohne mir ein eigenes SPI für Mirf schreiben/kopieren zu müssen.)

lg

: Bearbeitet durch User
von Frank K. (fchk)


Lesenswert?

Dont K. schrieb:

> Nur... Ist damit gemeint, dass ich vor jedem Zugriff den Modus umstellen
> muss? Oder gibt es eine Möglichkeit das von Anfang an zu definieren?

Du musst vor jedem Zugriff umstellen.

fchk

von Dont K. (dont_k)


Lesenswert?

Ok, danke dir!
Damit wäre das Problem gelöst.

von grundschüler (Gast)


Lesenswert?

Dont K. schrieb:
> Oder gibt es eine Möglichkeit das von Anfang an zu definieren?

das Macht man am Anfang mit defines:
1
#define lcd_CS_HIGH()    pinSET(lcd_CS_port,lcd_CS_pin)//;spimode_0
2
#define lcd_CS_LOW()    pinCLR(lcd_CS_port,lcd_CS_pin)//;spimode_3

von grundschüler (Gast)


Lesenswert?

grundschüler schrieb:
> //

Der Kommentar muss weg:
#define lcd_CS_HIGH()    pinSET(lcd_CS_port,lcd_CS_pin);spimode_0
#define lcd_CS_LOW()    pinCLR(lcd_CS_port,lcd_CS_pin);spimode_3

von Dont K. (dont_k)


Lesenswert?

Ok
Sieht interessant aus. Magst du mir vielleicht erklären was die Zeilen 
tun? Das sieht für mich nicht aus als ob mein Standard SPI das verträgt. 
Werden da irgendwelche Methoden überschrieben?

von grundschüler (Gast)


Lesenswert?

Dont K. schrieb:
> Ok
> Sieht interessant aus. Magst du mir vielleicht erklären was die Zeilen
> tun? Das sieht für mich nicht aus als ob mein Standard SPI das verträgt.
> Werden da irgendwelche Methoden überschrieben?

Das musst du nach deinem Code selbst definieren, z.B. für AVR:
#define spimode_0   SPCR&=~((1<<CPOL)|(1<<CPHA))
#define spimode_3   SPCR|=(1<<CPOL)|(1<<CPHA)

#define lcd_CS_HIGH()  PORTB|=1<<4;spimode_0

von Dont K. (dont_k)


Lesenswert?

Ok ich blick da zwar noch nicht ganz durch, werds mir aber anschaun.

thx

von W.A. (Gast)


Lesenswert?

Dont K. schrieb:
> Das sieht für mich nicht aus als ob mein Standard SPI das verträgt.
> Werden da irgendwelche Methoden überschrieben?

Das sind Definitionen für einfache Textersetzungen, die der C 
Preprozessor macht.

Von was für Methoden redest du. Irgendwie musst du doch bei dir der 
SPI-Mode eingestellen werden.

von Dont K. (dont_k)


Lesenswert?

Na ich glaub ich hatte das vorher mit der Textersetzung nicht ganz 
verstanden.

Gut die ersten beiden Zeilen sind recht klar, da werden einfach nur die 
SPI Modes gesetzt (an der definierten Stelle im Quellcode).

#define lcd_CS_HIGH()  PORTB|=1<<4;spimode_0

da wird im Quellcode lcd_CS_HIGH() mit PORTB|=1<<4;spimode_0 
überschrieben. am Ende brauche ich kein ; weil ja mit dem define auch 
keines ersetzt wird.

Was ich nicht ganz vestehe ist:
PORTB|=1<<4
Was bewirkt dieser Teil?
Ist das alles was lcd_CS_HIGH() sonst noch tun soll? Außer den SPI Mode 
setzen?

Das sind derzeit meine high/low Methoden
1
void adns_com_begin_L(){
2
  SPI.setDataMode(SPI_MODE3);
3
  digitalWrite(PIN_NCS_L, LOW);
4
  digitalWrite(PIN_NCS_R, HIGH);
5
}
6
7
void adns_com_begin_R(){
8
  SPI.setDataMode(SPI_MODE3);
9
  digitalWrite(PIN_NCS_L, HIGH);
10
  digitalWrite(PIN_NCS_R, LOW);
11
}
12
13
void adns_com_end(){
14
  digitalWrite(PIN_NCS_L, HIGH);
15
  digitalWrite(PIN_NCS_R, HIGH);
16
  SPI.setDataMode(SPI_MODE0);
17
}

: Bearbeitet durch User
von grundschüler (Gast)


Lesenswert?

PORTB|=1<<4; ;=> setze PIN_4 des Port_B auf high
ist - wenn PIN_NCS_L PortB/Pin4 entspricht - identisch mit
 digitalWrite(PIN_NCS_L, HIGH);
Es sind nur die Bezeichnungen aus dem Datenblatt/io.h und nicht von 
arduino.


irgendwo am Anfang von arduino stehen #defines, welches 
digitalWrite(x,y) entsprechend den Registern des AVR umdefinieren. z.B.:

#define GLUE(a, b)  a##b
#define PORT(x)          GLUE(PORT, x)
#define digitalWrite(x,y)  ((y) ? (PORT(x/4)|=(1<<(x%4)) : 
((PORT(x/4)&=~(1<<(x%4)))




deine  high/low Methoden sind ok.

von Dont K. (dont_k)


Lesenswert?

Ok Dankeschön. Inzwischen funktioniert es.

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.