Forum: Mikrocontroller und Digitale Elektronik DOG-M Display und SPI-Modul an einem SPI


von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Hallo miteinander,

ich habe ein Problem bei der Verwendung eines EA DOG-M Displays und 
eines SPI-Sensors, die ich gemeinsam am SPI-Bus absteuern will.

Ich habe mittels des Codes von hier:
Beitrag "EA DOGM162 an SPI"
das Display sehr schnell zum Laufen bekommen.

Die Auswertung des SPI-Sensors habe ich einem separaten Code auch 
ausgetestet.
Nun wollte ich eben beide Teile vereinen und leider funktioniert hier 
bzgl. Ansteuerung weder das eine noch das andere Modul.

Ich betreibe die Schaltung mit dem Atmega168, der SPI-Sensor hängt über 
Miso/Mosi und SS-Pin am µC, das Display, wie empfohlen am Controller.
Als gemeinsamer Leiter gibt es nur MOSI.

Gibt es bei der Ansteuerung irgendetwas besonderes zu beachten ?
Die SPI-Clock Einstellung bei der Initialisierung habe ich gleich 
eingestellt.

Es dürfte doch prinzipiell kein Problem sein, die beiden Module an einem 
SPI-Port zu haben, oder ?

Michael

von Stefan S. (mexakin)


Lesenswert?

Michael schrieb:
> Als gemeinsamer Leiter gibt es nur MOSI.

wieso?

entweder du nimmst denselben SPI für beide Module, dann sollte nur der 
Chipselect verschieden sein,w eil du mit dem ja das anzusprechende Modul 
wählst.

Oder du benutzt sowieso 2 unterschiedliche SPI Pins am µc falls der das 
überhaupt hat, und benutzt dann aber Konsequenterweise auch keine 
Signale doppelt...

von Martin (Gast)


Lesenswert?

Du hast einen Fehler in deinem Code in Zeile 259.

von Michael (Gast)


Lesenswert?

stefan schmitt schrieb:
> entweder du nimmst denselben SPI für beide Module, dann sollte nur der
> Chipselect verschieden sein,w eil du mit dem ja das anzusprechende Modul
> wählst.
>
> Oder du benutzt sowieso 2 unterschiedliche SPI Pins am µc falls der das
> überhaupt hat, und benutzt dann aber Konsequenterweise auch keine
> Signale doppelt...

Das Problem ist, das die beiden Module ja nur die MOSI Leitung gemeinsam 
haben. Du meinst, ich müsste hier konsequent beide Signale voneinander 
trennen oder auf einem gemeinsamen Port betreiben ?
Das nur die MOSI-Leitung gemeinsam ist, kann nicht funktionieren ?

von Michael (Gast)


Lesenswert?

Entschuldigung,
das Display hängt auch mit SCK am selben SPI-Leitung, als der Sensor.
Warum benötigt das Display keinen Miso-Anschluss ?

von spess53 (Gast)


Lesenswert?

Hi

>Warum benötigt das Display keinen Miso-Anschluss ?

Weil das Display nur Daten empfangen, aber nicht senden kann.

MfG Spess

von Michael (Gast)


Lesenswert?

spess53 schrieb:
> Weil das Display nur Daten empfangen, aber nicht senden kann.

Ah, na klar, Danke.
Dann hängt der Sensor und das Display ja an den gleichen SPI-Anschlüssen 
mit MOSI und SCK. Der Chipselect ist natürlich unterschiedlich, also 
eigentlich sollte ich es ja dann auch zum Laufen bringen können, falls 
es sonst nichts mehr zu beachten ist.

von grundschüler (Gast)


Lesenswert?

Michael schrieb:
> Die SPI-Clock Einstellung bei der Initialisierung habe ich gleich
> eingestellt.

Wenn beide Module mit dem gleichen Modus arbeiten, müsste das 
funktionieren. Ansonsten müsste beim chipselect jeweils der Modus 
geändert werden.

Vielleicht reicht die Stromversorgung nicht aus.

von Michael (Gast)


Lesenswert?

Unter ea_dog.h sind die Portdefinitinen aufgeführt:

//*******************************************
#define F_CPU    8000000UL  //Clockspeed in Hz
#define DDR_SPI  DDRB  // DD-Register des SPI-Ports
#define DD_MOSI  DDB3  // Port/Pin des MOSI
#define DD_SCK   DDB5  // Port/Pin des SCK
#define DD_RS    DDRB  // DDR von RS
#define PORT_RS  PORTB // Port an dem RS ist
#define PIN_RS   PB1   // Pin an dem RS ist
#define DD_CSB   DDRB  // DDR von CSB
#define PORT_CSB PORTB // Port an dem CSB ist
#define PIN_CSB  PB0   // Pin an dem CSB ist
#define VOLTAGE  5     // Voltage auf 5 oder 3 Volt
#define CONTRAST 0x73  // Von 0x73 bis 0x7F Hexadezimal

#define PORT_SS PORTB // Port an dem SPI Slave select ist
#define PIN_SS  PB2   // Pin an dem SPI Slave select ist
#define DD_SS   DDB2  // Port/Pin des SS SPI Slave select
//*******************************************

Die letzten drei Zeilen verwirren mich nun etwas.
An PORTB2 hängt nämlich der CS für die Ansteuerung des Sensors.

Unter Init SPI wird der dann ausgeschaltet, ist auch so kommentiert.

PORT_SS |= (1 << PIN_SS);  //SPI Slave select ausschalten!
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);

Ich habe nun die erste Zeile und 1<<DD_SS rausgelöscht, um  PB2 zu 
aktivieren, aber leider funktioniert es deshalb auch nicht.

von Michael (Gast)


Lesenswert?

Was ich nicht verstehe ist, dass in der Portdefinition PB2 als 
Slave-Select
ausgewählt ist:

#define PORT_SS PORTB // Port an dem SPI Slave select ist
#define PIN_SS  PB2   // Pin an dem SPI Slave select ist
#define DD_SS   DDB2  // Port/Pin des SS SPI Slave select

Der CS ist mit PORTB1 definiert:
#define PORT_RS  PORTB // Port an dem RS ist
#define PIN_RS   PB1   // Pin an dem RS ist

Tatsächlich ist das Display gar nicht mit PB2 verbunden, sondern mit 
PB1.
PB2 brauche ich als CS ja für meinen Sensor.

Verändere ich aber was an den PB2 Zeilen, funktioniert das Display nicht 
mehr.

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:
> Was ich nicht verstehe ist, dass in der Portdefinition PB2 als
> Slave-Select
> ausgewählt ist:

Das hängt damit zusammen, dass dir dein Mega einen SS Pin aufs Auge 
drückt.
Dieser Pin (der von Atmel vorgegeben ist) wird sinnvollerweise bei 
SPI-Master Betrieb als Ausgang konfiguriert, ansonsten handelt man sich 
einige Nebenbedingungen ein, damit der SPI-Master überhaupt 
funktioniert.

Daher haben wohl die Macher deiner LCD-Lib beschlossen genau das zu tun: 
den SS Pin als Ausgang zu konfigurieren.

> PB2 brauche ich als CS ja für meinen Sensor.

Was nichts daran ändert, dass du den Pin nach wie vor auf Ausgang 
schalten solltest. Wenn du diesen Pin für das CS von deinem Sensor 
benutzt, dann kannst du das natürlich tun. Ändert aber nichts daran, 
dass du den Pin auf Ausgang schalten musst.

Trenne dich von der Vorstellung, dass man ganz einfach 2 einzeln 
funktionierende Komponenten zusammenkopieren kann und alles läuft weiter 
wie gewohnt. Die Dinge müssen aneinander angepasst werden. Speziell 
dann, wenn sie eine gemeinsame Resource (hier ist das das SPI Modul) 
benuten. Und dazu ist es notwendig zu verstehen, warum manche Dinge 
scheinbar sinnloserweise gemacht werden. Wie bei dir das 'auf Ausgang 
schalten' des SS Pins des Megas. Das LCD braucht das nicht (ist ja uch 
nicht dort angeschlossen), aber das SPI Modul vom Mega braucht das, 
damit der Master Modus vom SPI problemlos funktioniert.

Tatsächlich hast du 3(!) Komponenten in deinem Programm
* das SPI Modul
* das LCD Modul
* das Sensor Modul

deine LCD Lib hat die Behandlung für 2 dieser Komponenten ineinander 
verwoben. Das ist auch gut so, solange du nur das LCD im System hast. 
Auf den Kopf fällt dir das genau dann, wenn du so wie hier weitere SPI 
Module brauchst. Ich würde mir die Arbeit machen und genau diese 
Trennung noch viel stärker im Code herausarbeiten. Da gibt es das 
SPI-Modul und in dessen Kompetenzbereich fällt das auf Ausgang schalten 
des SS Pins für den Master Modus (sowie natürlich die Konfiguration der 
restlichen Pins).
LCD und Sensor sind dann nur noch (konzeptionell) Benutzer dieses SPI 
Moduls.

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>Verändere ich aber was an den PB2 Zeilen, funktioniert das Display nicht
>mehr.

PB2 ist der /SS-Pin des SPI. Dazu gibt es einen eigenen Abschnitt:

SS Pin Functionality

im Datenblatt.

MfG Spess

von Michael (Gast)


Lesenswert?

Karl Heinz schrieb:
> Trenne dich von der Vorstellung, dass man ganz einfach 2 einzeln
> funktionierende Komponenten zusammenkopieren kann und alles läuft weiter
> wie gewohnt.

Ja schade das es nicht so einfach geht.
Ich habe eben zwei Codes, die ich irgendwie zusammenbringen muss.


Karl Heinz schrieb:
> Das hängt damit zusammen, dass dir dein Mega einen SS Pin aufs Auge
> drückt.

Ja stimmt, der eigentliche CS ist ja PORT_RS und nicht PORT_SS, den er 
aber im Comand-Befeht mitzieht.
Aber diese Zeilen muss ich ja irgendwie rausbekommen, weil er ja mit 
jedem Display-Befehl meinen Sensor an PB2 damit in Unruhe bringt.

// *******************************************************************

void Disp_Command(volatile int Data)
{
  PORT_SS |= (1 << PIN_SS);  //SPI Slave select ausschalten!

  _delay_us(50); // Angstzeit eingefügt  50 am 18.02.2013 Axel

  // Command Mode vorbeireiten; setze RS low
  PORT_RS &= ~(1 << PIN_RS);

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

  //Übertragung abschließen durch RS toggle
  PORT_RS |= (1 << PIN_RS); // high
  _delay_us(5); // Angstzeit 1 alt, geändert auf 5 am 18.02.2013 Axel
  PORT_RS &= ~(1 << PIN_RS); //low

  _delay_us(50); // warte auf Display
}
// *******************************************************************

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:

> Aber diese Zeilen muss ich ja irgendwie rausbekommen, weil er ja mit
> jedem Display-Befehl meinen Sensor an PB2 damit in Unruhe bringt.

Zeile
>   PORT_SS |= (1 << PIN_SS);  //SPI Slave select ausschalten!
im Editor markieren und auf 'entf' drücken.
:-)

von Karl H. (kbuchegg)


Lesenswert?

Der Code ist überhaupt in dieser Hinsicht recht schlampig geschrieben!

Der Pin, den es zu behandeln gegolten hätte, ist der CSB Pin. Der wird 
in dem Code aber recht stiefmütterlich behandelt. Nämlich so gut wie gar 
nicht. In der Init geht er auf Ausgang und dann auf Low und dort bleibt 
er auch.
D.h. das LCD ist dauern selected.

Wie schon gesagt: solange man nur das LCD am SPI hängen hat, geht das. 
Aber unter uns Klosterschwestern: Unter Codequalität in einer 
veröffentlichten Lib stelle ich mir was anderes vor.

von Michael (Gast)


Lesenswert?

Karl Heinz schrieb:
> Zeile
>>   PORT_SS |= (1 << PIN_SS);  //SPI Slave select ausschalten!
> im Editor markieren und auf 'entf' drücken.

Aber warum hat er die Zeile dann überhaupt noch drinnen ?
Wenn der PORT als Ausgang definiert sein muss, ist das ja verständlich,
aber warum er erst PORT_SS ausschalten muss, damit PORT_RS funktioniert 
ist mir nicht ganz klar.

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:
> Karl Heinz schrieb:
>> Zeile
>>>   PORT_SS |= (1 << PIN_SS);  //SPI Slave select ausschalten!
>> im Editor markieren und auf 'entf' drücken.
>
> Aber warum hat er die Zeile dann überhaupt noch drinnen ?

Schau dir den Rest des COdes an.
Die Antwort kann nur lauten: weil er es nicht besser wusste/konnte.

> Wenn der PORT als Ausgang definiert sein muss, ist das ja verständlich,
> aber warum er erst PORT_SS ausschalten muss, damit PORT_RS funktioniert
> ist mir nicht ganz klar.

Hold dir aus dem Code die Initsequenz, welche Bytes in welcher 
Reihenfolge zu senden sind, damit die Konfiguration vernünftig ist.
Den Rest des Codes schmeisst du weg und schreibst ihn nochmal ordentlich 
neu. Das geht schneller als zu ergründen, was der Autor sonst noch so 
alles nicht verstanden hat, vergessen hat oder sonst irgendwie verbockt 
hat.

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