Hallo,
ich möchte einen Attiny2313 als slave in einem SPI-Bus benutzen.
allerdings habe ich probleme die Daten richtig zu empfangen.
1
ISR(INT0_vect){
2
while(!(USISR& (1<<USIOIF)))
3
spi_data = USIDR;
4
new_spi_data = 1;
5
}
new_spi_data frage ich dann in der main-schleife ab. Allerdings bekomme
ich nur 0x00 als daten. egal was ich sende. spi_data ist dabei als
volatile definiert.
Am Master funktioniert die Übertragung richtig. Ich bekomme die Daten
auch richtig zurück. Also kann es schon einmal nicht total verkehrt
sein.
weiss einer, wie ich die Daten bei einem Attiny richtig abfragen muss?
Kimmy schrieb:> Am Master funktioniert die Übertragung richtig. Ich bekomme die Daten> auch richtig zurück. Also kann es schon einmal nicht total verkehrt> sein.> weiss einer, wie ich die Daten bei einem Attiny richtig abfragen muss?
Poste mal dein Programm, es ist meistens so, dass irgendetwas ganz
anders ist als in Fragestellung.
Verstehe das sowieso nicht:
"Ich habe ein Problem mit meinem Programm aber den poste ich nicht,
weil absolut unwichtig, alles andere stimmt 100%".
Wie ist new_spi_data deklariert ?
Was hat INT_0 ISR mit SPI zu tun ?
INT0 ist quasi mein SlaveSelect, da ich anders nicht weiss wie ich
mitbekommen kann, dass der Master etwas gesendet hat. Wenn der Master zu
senden anfängt, setzt er diesen Pin auf Low, wodurch die ISR aufgerufen
wurde.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
#define F_CPU 8000000UL // for _delay_ms(); _delay_us()
Zwei Schreibfehler:
> DDRB &= ~(1 << DDD2); // External Interrupt on INT0> DDRB |= (1<<PORTD5); // PD5 -> Output
Wird nicht mit Letzerem MOSI auf Ausgang geschaltet?
Das stimmt, war beides falsch geschrieben.
Habe die pins jetzt auf dem richtigen Port gelegt.
> DDRD &= ~(1 << DDD2); // External Interrupt on INT0> DDRD |= (1<<PORTD5); // PD5 -> Output
Doch leider erhalte ich immer noch nur 0x00 als ergebnis
Habe das in der ISR zum schluss eingefügt und bei der initialisierung.
Das hat aber gebracht, dass ich zunächst völlig falsche werte erhalte
und nach ein paar mal senden (ca. 8mal ) gar nichts mehr empfangen wird.
auch mit = anstelle von |= habe ich gleiches verhalten. Das müsste doch
auch eigentlich egal sein oder? es wird doch nur das bit USIOIF
berücksichtigt. dann ist es doch egal ob |= oder = oder nicht?
Es wird doch empfangen, war ein Wackelkontakt.
Allerdings falsch und zwar bekomme ich beim Slave sowohl als auch beim
Master 0xFF heraus. egal was ich sende
S. Landolt schrieb:> Leitungen MOSI <-> MISO vertauscht?
nein, wenn ich aber die sck leitung trenne, findet der sich wieder
zurecht.
dann funktioniert auch die Übertragung. Das richtige Ergebnis wird auch
übertragen.
Aber das widerspricht meinen Kenntnissen von SPI. Eigentlich schiebe ich
doch vom Master die Daten rein und lese diese sofort (bzw. die die davor
gesendet wurden und in USISDR stehen) wieder aus.
Jetzt schreibe ich aber einen anderen Wert in USISDR rein. Diese erhält
dann auch der Master. Aber das sind ja nicht die, die ich vorher
gesendet habe
Wie sieht das Senden auf dem Master aus? Nach dem Setzen von /SS muss
eine gewisse Verzögerung vorhanden sein, bevor SPI gestartet wird;
schließlich benötigt der Slave etwas Zeit, um in die INT0-ISR zu
gelangen.
Wenn ich das am ende der ISR schreibe, bekomme ich immer falsche
Ergebnisse und irgendwann bleibt es hängen. Wenn ich das am anfang
hinschreibe, sind die Ergebnisse richtig aber es bleibt trotzdem hängen.
Beim Master setze ich den pin auf low, warte 10ms und fange dann mit dem
ÜBertragen an.
Ich lasse mir die Übertragenen Daten in der mein-Schleife anzeigen, also
wenn die ÜBertragung eigentlich schon lange vorüber ist. Trotzdem bleibt
es hängen, wenn ich es erst dann neue Daten sende.
Das Programm hat sich nicht wirklich geändert, bis auf die Tippfehler
(DDRB-> DDRD) und USISR = (1<<USIOIF); in der initialisierung und in
der ISR eingefügt.
Aber wenn USISR = (1<<USIOIF); am anfang von der ISR steht, läuft das
alles noch ein bisschen stabiler.
Gesendet wird ganz langsam. Das mache ich über den Computer zum Master.
Dieser empfängt die Daten über UART und gibt diese über SPI weiter.
Im Slave in der HAuptschleife lasse ich mir das Ergebnis ausgeben (auch
das rückgabeergebnis vom Master lasse ich mir ausgeben). Erst wenn alles
ausgegeben ist, schicke ich neue Daten. Also zu schnell dürfte das ganze
nicht sein. Beim Master ist es so, dass dieser den Pin für die ISR auf
Low zieht und dann 10ms wartet, bevor die Übertragung startet
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
#define F_CPU 8000000UL // for _delay_ms(); _delay_us()
Für mich sieht das Slave-Programm okay aus (vom belanglosen
Schreibfehler DDRB &= ~(1 << DDD2) mal abgesehen). Ich würde jetzt den
Fehler eher in der Verdrahtung oder auch im Master suchen, aber so
richtig erklären kann ich mir das Fehlverhalten, speziell das
Hängenbleiben, nicht.
"The Universal Serial Interface, or USI... Three-wire Synchronous Data
Transfer (Master, fSCKmax = fCK/2, Slave fSCKmax = fCK/4)"
Die letztere Bedingung ist erfüllt?