Forum: Mikrocontroller und Digitale Elektronik GCC Atmega32 + Atmega8 SPI Kommunikationsproblem


von Dj E. (djelko)


Lesenswert?

Hallo, Leute!

Nach vielen mehr oder weniger erfolgreichen Projekten mit 
Mikrocontrollern wollte ich mich mit der SPI-Schnittstelle beschäftigen.

Der Atmega32 arbeitet als Master, der Atmega8 als Slave.
Verbindungen siehe Schaltplan.
Der Atmega32 wird mit dem internen 8Mhz Oszillator getaktet,
der Atmega8 laut Buch hingegen mit dem internen 1Mhz Oszillator.

Den Code sowie den Schaltplan habe ich aus dem Buch "Hardware und 
C-Programmierung in der Praxis".

Dort wurde zwar der Atmega16 + 8 verwendet, was aber nach einer Änderung 
im Makefile keinen Unterschied machen sollte.

Am Atmega32 (Master) ist ein Lcd angeschlossen, welches tadellos 
funktioniert, wobei der RW-Pin auf GND gezogen werden musste
(im Buch steht, dass man ihn nicht zu beschalten hat?!).

Der Atmega32 sendet dem Atmega8 nun die Zahl "1".
Der Atmega8 prüft, ob diese Zahl "1" entspricht und sendet daraufhin 
"100" zurück.
Der Atmega32 soll dann diese "100" ausgeben.

Soweit so gut, aber der Atmega32 schreibt auf das Lcd mehr oder weniger 
zufällige Zahlen wie:
sehr häufig 255
031
087
251
239
243
usw...

Leider habe ich momentan kein Oszi zur Verfügung, um die Kommunikation 
zu überprüfen, aber wenn ich eine Led an Miso, Mosi oder Sck hänge, dann 
blitzt sie kurz auf (jenachdem ob ich sie nach VCC oder GND beschalte).

Es findet also eine Kommunikation statt.

Komischerweise blitzt die Led (wenn sie an Miso angeschlossen ist) 
manchmal hell auf, manchmal nur ganz schwach...

Während dem Programmieren hänge ich natürlich den anderen AVR vom 
Programmer ab.
Während des Betriebs ist der Programmer (bis auf VCC + GND) auch nicht 
angeschlossen.
Die VCC kommen aus meinem USB-Programmer.
Das ganze habe ich auf einem Steckbrett aufgebaut.

Hat jemand eine Idee, warum sich diese Schaltung so verhält und wie man 
eine stabile Kommunikation zwischen den µCs herstellen kann?

Danke im Voraus
Gruß DjElko! :-D

von Dj E. (djelko)


Angehängte Dateien:

Lesenswert?

Natürlich die Anhänge vergessen...
Info: Ich programmiere in WinAVR mit Programmers Notepad.

von Dj E. (djelko)


Lesenswert?

Mir ist aufgefallen: extrem selten (jedes gefühlte 578. mal kommt 100 am 
Atmega32 an und die Led am Atmega8 leuchtet auf...
Ich denke, es hat etwas mit den Zeiten zu tun (z.B. dass der Atmega8 
nicht hinterherkommt)...
Hat jemand eine Idee? Ich werde jetzt mal den Atmega32 mit 1Mhz 
takten...

von Dj E. (djelko)


Lesenswert?

Hm... auch mit 1Mhz gehts nicht besser...
Einziger Unterschied: Die Lcd-Darstellung benötigt mehr Zeit...

von Spess53 (Gast)


Lesenswert?

Hi

>Der Atmega32 sendet dem Atmega8 nun die Zahl "1".
>Der Atmega8 prüft, ob diese Zahl "1" entspricht und sendet daraufhin
>"100" zurück.
>Der Atmega32 soll dann diese "100" ausgeben.


>char SPI_MasterReceive(void)
>{
>  while(!(SPSR & (1<<SPIF)));    // warte bis Empfang komplett
>  return SPDR;          // empfangenes Byte >zurueckgeben
>}

Das funktioniert so nicht. Damit der Master etwas empfangen kann muss er 
ein Dummy-Byte senden. Der Slave erzeugt keinen Takt auf dem, den 
bekommt er vom Master und dazu muß der Master etwas senden.

MfG Spess

von Dj E. (djelko)


Lesenswert?

Ah, klar. Danke!
Der Slave hat ja kein Taktsignal, worauf er zurückgreifen kann...
Da muss man ersteinmal drauf kommen...
Wie realisiert man das denn in der Programmierung, dass der Master 
"weiß", wann der Slave sendet?

von Spess53 (Gast)


Lesenswert?

Hi

>Wie realisiert man das denn in der Programmierung, dass der Master
>"weiß", wann der Slave sendet?

Ein Slave sendet nicht, er wird 'gefragt'. Im einfachsten Fall sendet 
der Master zyklisch etwas an den Slave und wertet die Antwort aus.

Du könntest natürlich auch eine zusätzliche Leitung benutzen mit der der 
Slave sein Mitteilungsbedürfnis signalisiert.

Persönlich bevorzuge ich zu Kommunikation zwischen Controllern U(S)ART.

MfG Spess

von holger (Gast)


Lesenswert?

>Persönlich bevorzuge ich zu Kommunikation zwischen Controllern U(S)ART.

Ich auch. An SPI schliesse ich nur dumme Slaves an die in der
Lage dazu sind sofort etwas zu antworten. Bei einem uC SPI Slave
weiss man nie wann der antworten kann. Also muss man entweder lang
genug warten oder weitere Leitungen für ein Handshake einsetzen.
Allerdings könnte der Slave zum Master werden wenn er die SS
Leitung vom Master beackert. Naja, viel Spass dabei.

von Moritz A. (moritz_a)


Lesenswert?

Spess53 schrieb:
> Du könntest natürlich auch eine zusätzliche Leitung benutzen mit der der
> Slave sein Mitteilungsbedürfnis signalisiert.

Als dreckige Lösung habe ich dafür auch mal !SS verwendet, im Master 
über de Pullup High geschaltet und den Pin als Eingang. Möchte der Slave 
Daten loswerden, zuppelt er das mal kurz auf Masse, und schon kann der 
Master seine Dummyload rüberschicken um das Ergebnis abzuholen.

von Spess53 (Gast)


Lesenswert?

Hi

>Als dreckige Lösung habe ich dafür auch mal !SS verwendet, im Master
>über de Pullup High geschaltet und den Pin als Eingang.

Damit wechselt der Master aber erst in den Slavemode und muß erst mal 
wieder in den Mastermode geschaltet werden,

MfG Spess

von holger (Gast)


Lesenswert?

>Möchte der Slave
>Daten loswerden, zuppelt er das mal kurz auf Masse, und schon kann der
>Master seine Dummyload rüberschicken um das Ergebnis abzuholen.

In dem Fall muss der Slave den Takt erzeugen. Der Ex-Master kann
gar kein Dummy Byte mehr schicken wenn er zum Slave geworden ist.

von Moritz A. (moritz_a)


Lesenswert?

Der Master wird nirgends zum Slave. Nur hat die Slave-Leitung den 
angenehmen Effekt, dass sie Active-Low ist. Somit kann der Master über 
einen High-Pegel den Slaves signalisieren, dass sie gerade nicht aktiv 
sind. Soweit der normale Betrieb.

Nun kann ich aber statt einem High-Ausgangspin das Nicht-Aktiv-High auch 
über den (internen) Pullup erzeugen, und damit dem Slave die Möglichkeit 
geben es runterzuziehen. Der Master bemerkt diesen Pegelwechsel, im 
einfachsten Fall hat er einen Interrupt drauf, der ein passendes Flag 
setzt.

Nun weiß er (weiterhin in seiner Funktion als Master) dass der Slave 
Daten für ihn hat, und kann sie bei Gelegenheit abholen. Wo der Master 
nun zum Slave geworden sein sollt müsst ihr mir noch erläutern.

Das ist nichts anderes als der Interrupt-Ausgang, den viele fertige 
SPI-Chips sowieso haben, ohne dass ich einen weiteren Pin dafür brauche.

von Dj E. (djelko)


Lesenswert?

Danke für die vielen Antworten!

Ich glaube, ich werde zur Kommunikation zwischen mehreren µCs
doch I²C nehmen...

Mein Vorhaben ist es, mehrere Module mit einer gleichen Schnittstelle 
(z.B SPI oder I²C) zu bauen, um dann auf dem Steckbrett modular mit 
diesen Bausteinen arbeiten zu können. Bei 4-8 7-Segment-Anzeigen, einem 
Display (zum Debuggen) und einem Tastenfeld werden die Pins und auch der 
Platz auf dem Steckbrett sowie dem Atmega32 zu wenig...

Außerdem hat die Verwendung mehrerer Mikrocontroller (zumindest bei 
Versuchsaufbauten und zum Lernen der Programmierug) den Vorteil, dass 
der Hauptmikrocontroller "gemütlich" das Hauptprogramm abarbeiten kann 
und sich die anderen Mikrocontroller um die Kommunikation mit der 
Außenwelt kümmern.

UART wollte ich nicht nehmen, weil ich das ja schon vom PC sowie dem 
Haupt-µC "belegt" ist.

Ich mache mal ein Paar Versuche mit I²C; vielleicht funktioniert das ja 
besser. ;-D

Gruß, DjElko!

von Dj E. (djelko)


Angehängte Dateien:

Lesenswert?

Hm...
Mit I²C komme ich auch nicht wirklich weiter...
Ich möchte vom Atmega32 (Master) was zum Atmega8(Slave) senden und 
umgekehrt...
Kennt jemand einen Link oder so für eine funktionierende Master + Slave 
Library für I²C?
Ich bin langsam ratlos...
Hab es jetzt schon mit einigen Codes versucht, unter anderem mit dem 
hier:
Beitrag "AVR TWI Master und Slave Funtionen in C"
Leider kommt bei mir beim Compilieren der TWI_Master_main.c in 
Programmers Notepad + WinAVR folgende Fehlermeldung:
1
Linking: TWI_Master_main.elf
2
avr-gcc -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=16000000UL  -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=TWI_Master_main.o  -std=gnu99 -MD -MP -MF .dep/TWI_Master_main.elf.d TWI_Master_main.o --output TWI_Master_main.elf -Wl,-Map=TWI_Master_main.map,--cref    -lm
3
TWI_Master_main.o: In function `main':
4
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:51: undefined reference to `Delayloop32'
5
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:55: undefined reference to `RS232_Init'
6
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:60: undefined reference to `TWIM_Init'
7
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:75: undefined reference to `TWIM_Start'
8
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:77: undefined reference to `TWIM_Stop'
9
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:84: undefined reference to `TWIM_ReadAck'
10
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:87: undefined reference to `TWIM_ReadNack'
11
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:89: undefined reference to `TWIM_Stop'
12
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:90: undefined reference to `Delayloop32'
13
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:97: undefined reference to `TWIM_Start'
14
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:99: undefined reference to `TWIM_Stop'
15
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:106: undefined reference to `TWIM_Write'
16
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:109: undefined reference to `TWIM_Stop'
17
D:\Erstellungen - Master-Ordner\Hobby\Elektro\uC\avr_gcc_neu\i2c_topic\TWI_Master/TWI_Master_main.c:110: undefined reference to `Delayloop32'
18
make.exe: *** [TWI_Master_main.elf] Error 1
19
20
> Process Exit Code: 2
21
> Time Taken: 00:01

Hat jemand einen Tipp oder eine Lösung? Das Problem wurde zwar auch in 
dem oben genannten Thread beschrieben, doch eine wirkliche Lösung hat da 
keiner gefunden...

Gruß, DjElko!

von holger (Gast)


Lesenswert?

>Hat jemand einen Tipp oder eine Lösung?

Du hast TWI_Master.c und Delay.c nicht zum Projekt hinzugefügt.
Einfach in das Verzeichnis kopieren reicht nicht.

von Dj E. (djelko)


Lesenswert?

Heureka! :-D
Es funktioniert! :-D Vielen Dank für die Unterstützung! :-D
Ein paar Änderungen mussten noch im Makefile des Slaves vorgenommen 
werden.

Gruß, DjElko!

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.