Hallo zusammen,
ich habe schon das ganze Forum dursucht und alles gefundene bereits
ausprobiert. Aber es will einfach nicht funktionieren. Hier mein
Problem:
Habe eine kleine Schaltung mit einem Attiny25, die eine Spannung misst.
Die Schaltung ist in einer Dose verbaut. Nun habe ich mehrere von diesen
Schaltungen. Nun habe ich mir für Log-Zwecke eine Schaltung mit einem
Atmega8 genommen an die ein LCD angeschlossen ist. Mit dem Atmega8
möchte ich über SPI die vom Attiny25 gemssene Spannung am LCD anzeigen
lassen. Ich habe auf beiden Schaltungen lediglich die ISP-Buchse zum
Programmieren. Da ich die kleinen Schaltungen nicht mehr abändern kann,
möchte ich den Attiny25 und Atmega8 über die vorhandenen ISP-Buchsen
miteinander verbinden. habe mir ein 1:1 Kabel angefertigt, mit den ich
die zwei Buchsen verbinde.
Ich habe mehrere Codes aus dem Forum probiert aber es funktioniert
einfach nicht. Noch zur Info, der Attiny25 benutzt den internen Takt mit
2MHz und der Atmega8 einen externen Quarz mit 8MHz. Bei den ISP-Buchen
handelt es sich um die 10-Poligen Buchsen.
Kann mir jemand sagen ob die zwei Schlatungen über die ISP-Buchsen
miteinander per SPI kommunizieren können?
Wenn ja, würde ich mich über ein Minimal-Code sehr freuen.
Viele Grüße
Cetin
>habe mir ein 1:1 Kabel angefertigt, mit den ich>die zwei Buchsen verbinde.
hoffe das ist kein meter kabel?
>der Attiny25 benutzt den internen Takt mit>2MHz und der Atmega8 einen externen Quarz mit 8MHz.
wenn der atmega8 der master ist darf die takt rate von sck nur maximal
1/4 von dem attiny25 sein. (<= 500khz)
>Kann mir jemand sagen ob die zwei Schlatungen über die ISP-Buchsen>miteinander per SPI kommunizieren können?
klar geht das, die pins an der buchse haben fast alles was du brauchst
mosi, miso und sck.
eigentlich fehlt nur noch ss um den slave auszuwählen was aber nicht
notwendig ist wenn du nur mit einem slave kommunizierst da du hier fest
einstellen kannst wer mast und wer slave spielt.
>Wenn ja, würde ich mich über ein Minimal-Code sehr freuen.
datenblatt seite 127, master-init und seite 128 slave-init.
Danke für die schnelle Antwort.
> hoffe das ist kein meter kabel?
nein, das Kabel ist ca. 20cm lang.
> wenn der atmega8 der master ist darf die takt rate von sck nur maximal> 1/4 von dem attiny25 sein. (<= 500khz)
habe bisher versucht den Attiny25 als Master einzustellen. Werde nun
aber den Atmega8 als Master einstellen, macht vermutlich mehr Sinn.
> datenblatt seite 127, master-init und seite 128 slave-init.
Die Seite kenne ich, für den Atmega8 benutze ich auch den Code.
Beim Atmega8 gibt es aber für den Master nur die Sende-Routine, wie
kann ich mit dem Master Daten empfangen?
Beim Attiny25-Datenblatt gibt es keinen Beispiel-Code in C, nur in
Assembler.
>Beim Atmega8 gibt es aber für den Master nur die Sende-Routine, wie>kann ich mit dem Master Daten empfangen?
wären die daten im takt zum slave übertragen werden, überträgt der slave
seine daten an den master.
also einfach nach dem senden das register auslesen, darin stehen die
empfangenen daten.
>Beim Attiny25-Datenblatt gibt es keinen Beispiel-Code in C, nur in>Assembler.
wenn du verstanden hast wie man spi initialisiert und verwendet, kann
man das auch ohne beispiel.
> wären die daten im takt zum slave übertragen werden, überträgt der slave> seine daten an den master.> also einfach nach dem senden das register auslesen, darin stehen die> empfangenen daten.
OK, habe ich verstanden.
> wenn du verstanden hast wie man spi initialisiert und verwendet, kann> man das auch ohne beispiel.
Naja, so grob habe ich verstanden wie SPI funktioniert. Es sind meistens
Kleinigkeiten die mir fehlen damit ein Programm läuft. Es Beispiel-Code
finde ich hilfreicher, da ich hier das wichtigste drin habe und den Code
richtig analysieren kann und es so besser verstehe.
Wie ist es eigentlich, wenn ich den Attiny25 als Slave einrichte, wie
bekomme ich mit, das der Master ein Verbindung aufgebaut hat. Muß ich
das ganze über Interrupts machen oder kann man auch kurz in ein Register
schauen und weiß dann ob Verbindung besteht oder nicht? Oder muß der
Slave die ganze Zeit auf Verbindung warten und der Controller kann
nichts anderes machen?
>Es Beispiel-Code>finde ich hilfreicher, da ich hier das wichtigste drin habe und den Code>richtig analysieren kann und es so besser verstehe.
klar, ganz ohne beispiel ist schlecht aber genau deshalb ist ein
assembler beispiel dabei um zu verstehen was man dem chip genau sagen
muss.
>Muß ich>das ganze über Interrupts machen oder kann man auch kurz in ein Register>schauen und weiß dann ob Verbindung besteht oder nicht?
genau, entweder über interrupt oder pollen.
Im Datenblatt vom Attiny25 habe ich folgende Belegung gesehen:
Master: Slave:
DI -----> DO
DO -----> DI
USCK -----> USCK
Das würde doch bedeuten, das ich das mit meinem 1:1 Kabel nicht machen
kann. Muss ich im Kabel nun Mosi und Miso überkreuzen oder funktioniert
es 1:1 ?
>Muss ich im Kabel nun Mosi und Miso überkreuzen oder funktioniert>es 1:1 ?
MOSI = master in slave out
MISO = master out slave in
SCK = takt
SS = slave select
also alles 1 zu 1 verbinden.
>Beispiel-Code in C wäre ich trotzdem dankbar
sorry, damit kann ich auf die schnelle nicht dienen.
aber ich habe versucht den assembler code für dich mit kommentaren
verständlich zu machen.
init:
ldi r16,(1<<USIWM0)|(1<<USICS1) ;USICR = USIWMO und USICS1 = 1
out USICR,r16
SlaveSPITransfer:
out USIDR,r16 ;zu sendendes datenbyte in USIDR
laden
ldi r16,(1<<USIOIF)
out USISR,r16 ; USISR = USIOIF=1
SlaveSPITransfer_loop:
in r16, USISR
sbrs r16, USIOIF ; solange USISR in USIOIF 0 ist ->
rjmp SlaveSPITransfer_loop ; springe SlaveSPITransfer_loop
in r16,USIDR ; empfangenes datenbyte abholen
ret ; rücksprung zum main programm
so, jetzt habe ich mal zwei kleine Programme geschrieben. Es scheint so
halber zu funktionieren, ich bekomme vom Slave nur einmal ein Wert
zugeschickt. Obwohl ich in meinem programm ja einen Zähler habe der
jedes mal was anderes schicken soll. Ich vermute das der Fehler am Slave
liegt.
Eins ist mir noch nicht so klar, wie kann ich mit Polling abfragen ob
etwas vom Master angekommen ist? Ist es per Interrup einfacher?
Sieht jemand den Fehler?
Master-Programm auf Atmega8
>Eins ist mir noch nicht so klar, wie kann ich mit Polling abfragen ob>etwas vom Master angekommen ist?
schau dir mal z.b. beim atmega8 auf seite 131 das "Bit 7 – SPIF: SPI
Interrupt Flag" an.
entweder du fragst das bit per polling ab oder du nimmst den spi
interrupt der dann ausgelöst wenn das bit gesetzt ist.
>void SPI_MasterInit(void)>{> // Set MOSI and SCK output, >>>>all others input<<<<> DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
wenn das spi fest auf master eingestellt werden soll ohne den ss pin zu
benutzen muss ss als ausgang geschalten sein.
seite 129 SS Pin Functionality. :)
Ich bin echt am Verzweifeln, habe nochmal das Datenblatt vom Attiny25
gründlich durchgelesen. Habe meinen aktuellen Code unten aufgeführt.
Mein LCD zeigt gar nichts an. Schaut doch mal bitte über mein Code,
vielleicht findet ihr ein paar Fehler.
Master (Atmega8)
> // DO und USCK als Ausgänge initialisieren
sck wird schon vom master als ausgang benutzt, er gibt den takt vor.
also muss usck beim slave ein eingang sein.
so hat jetzt ausgang gegen ausgang gekämpft, hoffentlich ist nix kaputt.
so sollte es beim slave funktionieren:
1
voidSPI_SlaveTransmit()
2
{
3
// Zählwert übergeben
4
USIDR=counter;
5
// bit von der vorherigen übertragung löschen um pollen zu können.
6
USISR=(1<<USIOIF);
7
//Warten bis daten abgeholt worden sind.
8
while(!(USISR&(1<<USIOIF)));
9
counter++;
10
if(counter>10)counter=0;
11
}
12
13
intmain(void)
14
{
15
SPI_SlaveInit();
16
while(1)
17
{
18
SPI_SlaveTransmit();
19
}
20
}
der slave legt nur die daten in das spi register und wartet solange bis
sie vom master abgeholt wurden.
> sck wird schon vom master als ausgang benutzt, er gibt den takt vor.> also muss usck beim slave ein eingang sein.> so hat jetzt ausgang gegen ausgang gekämpft, hoffentlich ist nix kaputt.
Juhu, jetzt geht es. Das Problem lag wirklich daran, das ich beide SCK's
als
Ausgang definiert habe. Es ist nichts kaputt gegangen.
Ich danke dir für deine gute und schnelle Hilfe.
Gruß
Cetin
Ich bin es nochmal. Jetzt habe ich noch folgendes Problem:
> der slave legt nur die daten in das spi register und wartet solange bis> sie vom master abgeholt wurden.
Auf dem Attiny25 soll ja eigentlich ein Programm laufen und erst wenn
der Master daten will, soll der Slave das Programm unterbrechen und die
Daten dem Master zur Verfügung stellen.
1.) Macht es was aus, wenn der Slave nicht daruaf wartet bis die Daten
abgeholt worden sind, sprich kann ich folgende Zeile auch weglassen?
--> while(!(USISR & (1<<USIOIF)));
2.) Am besten wäre es ja mit einem Imterrupt, aber so wie ich es
verstanden
habe, ist die Starterkennung nur bei TWI verfügbar. Bei SPI würde
das Bit
USISIE bei jedem Impuls gesetzt werden, oder?
3.) Wie kann ich beim Slave auf dem Attiny25 das Empfangen per Interrupt
realisieren?
Cetin A. schrieb:> Auf dem Attiny25 soll ja eigentlich ein Programm laufen und erst wenn> der Master daten will, soll der Slave das Programm unterbrechen
Dafür würde man normalerweise ein slave select Signal benutzen. Das
hast du aber bei deinem vorgegebenen Pinout nicht zur Verfügung.
Das Dumme an SPI ist, dass es keinerlei Vorkehrungen dafür hat, dass
der slave Zeit bekommt, sich erst einmal auf die Anforderung des
Masters vorzubereiten (selbst nicht mit einem slave select). SPI
ist bestens geeignet für ein Hardware-Schieberegister o. ä. als slave,
für einen Controller ist es nicht so sehr praktisch, und in deiner
Situation erst recht nicht.
Vielleicht willst du ja doch besser TWI machen? Dort gibt es die
Möglichkeit, dass der slave die initiale Kommunikation so weit
heraus zögert, bis er bereit ist, auf die Anfrage zu reagieren.
> Vielleicht willst du ja doch besser TWI machen?
Das Problem ist, das in der Schaltung auf dem der Atmega8 sitz, die
TWI-Pins bereits für ein normales LCD benutz wird(kein I²C-LCD) benutzt
wird. Und da dachte ich, bevor ich da anfange Leiterbahnen zu
unterbrechen und alles zurecht zu biegen, benutze ich leiber SPI und
kann ganz bequem die vorhandene ISP-Buchse verwenden. Und jetzt nach
Tagen wo ich endlich das SPI zum Laufen bekommen habe, möchte ich nicht
alles über den Haufen werfen und mit TWI anfangen.
Ich mache jetzt erstmal das SPI fertig, bevor ich wieder mit einem neuen
Thema anfange.
Das muß doch irgendwie gehen, dass der Slave erst reagiert wenn eine
Anfrage vom Master kommt, oder?
Was spricht dagen, wenn ich den Counter im Statusregister abfrage und
sobald dieser die Zahl 1 hat, springe ich in die Empfangsroutine und
warte dort noch bis das komplette Byte angekommen ist. Würde das
funktionieren?