Arbeite zurzeit an einem kleinen Projekt für mein Studium.
Hänge leider aber am eher leichten Teil des Ganzen an einem
wahrscheinlich trivialen Fehler, den ich aber nicht finde.
Ich soll mittels SPI Werte von einem ADC (MCP3302 / µC: AT90USB162)
einlesen.
Hab das ganze jetzt mal ausprogrammiert, jedoch das Problem, das nur die
erste Übertragung beim Start des µC erfolgreich ist.
Ich bekomme also am Anfang einen Wert (der richtig ist) und dann nichts
mehr.
Habe die SPI wie folgt initialisiert:
1
// SPI Enable, Mastermode, clock rate: fck/64
2
SPCR|=(1<<SPE)|(1<<MSTR)|(1<<SPR1);
3
DDRB|=(1<<PB2)|(1<<PB1);// MOSI and SCK as output
4
DDRB|=(1<<PB4);// CS also as output ...
5
PORTB|=(1<<PB4);// .. and set to "H"
6
DDRB&=~(1<<PB3);// MISO must be an input
Meine sende/lese Routine schaut so aus:
1
unsignedcharspi_ReWr(unsignedcharbyte)
2
{
3
SPDR=byte;
4
while(!(SPSR&(1<<SPIF)));
5
returnSPDR;
6
}
Die Controllbytes habe ich aus dem Datenblatt des MCP3302 (auch schon
mehrfach kontrolliert).
Die gesamte Routine wird ständig im Hauptprogramm aufgerufen.
Und wie schon am Anfang erwähnt, genau einmal funktionierts und dann
hängt das Programm.
Hat jemand eine Idee, wo der Fehler sein könnte?
Ok, hab den Fehler schon gefunden.
Ich habe Aufgrund des Layouts eine Doppelbelegung bei manchen IO-Pins.
Blöderweise hängen meine LED, mittels denen ich das Ergebnis anzeigen
will, an den gleichen Pins wie die SPI Pins (zwischen den LEDs und den
IO-Pins ist lediglich ein Latch).
Den Ablauf hab ich mir wie folg vorgestellt.
Latch deaktivieren -> SPI aktivieren -> Wert einlesen -> SPI
deaktivieren -> Latch aktivieren -> Wert auf LED ausgeben -> ...
Aber irgendwie funktioniert das mit dem SPI aktivieren/deaktivieren
nicht.
Hab schon diverse Methoden versucht, nur das SPE Bit setzen/löschen,
alle Bits des Controllregisters setzen/löschen, ...
Hat bis jetzt leider nichts funktioniert.
Muss ich beim reaktivieren des SPI irgendetwas besonderes beachten (zB
Register löschen/setzten, etc)?
Kann der MCP abstürzen, wenn sich am CS etwas tut?
Es werden, wenn das SPI deaktiviert ist, auch Daten auf PB4 geschrieben.
Bevor ich das SPI wieder aktiviere, sorge ich dafür, dass PB4 "H" ist,
danach wird SPI aktiviert, dann wird PB4 "L". Nach der Übertragung
wieder "H".
Könnte das den Fehler auslösen, dass der MPC entweder abstürzt, oder auf
irgendetwas wartet?
Hallo!
Ich kann leider selbst bei der Problemlösungsfindung nicht weiterhelfen.
Allerdings verstehe ich das hier nicht:
1
unsignedcharspi_ReWr(unsignedcharbyte)
2
{
3
SPDR=byte;
4
while(!(SPSR&(1<<SPIF)));
5
returnSPDR;
6
}
...würd ich aber gerne, weils mir nach einer eleganten Lösung aussieht,
auf die ich nie gekommen wäre. Falls mir das jemand kurz "ausdeutschen"
könnte wäre ich sehr dankbar :)
Hoffe das ist ok hier zu fragen; da kann ich was Lernen!
Besten Dank,
Sebastian
Du gibts ein Byte ins Senderegister, wartest bist das Byte gesendet
wurde. Zur gleichen Zeit wird ein Byte ins Empfangsregister geschoben,
welches man mit dem gleichen Registernamen (SPDR) auslest.
Ich hoffe das die Formulierung zumindest halbwegs verständlich ist.
Dominik W. schrieb:> Kann der MCP abstürzen, wenn sich am CS etwas tut?
?? wie macht sich den die Fehlfunktion bemerkbar?
> Es werden, wenn das SPI deaktiviert ist, auch Daten auf PB4 geschrieben.> Bevor ich das SPI wieder aktiviere, sorge ich dafür, dass PB4 "H" ist,> danach wird SPI aktiviert, dann wird PB4 "L". Nach der Übertragung> wieder "H".
dem MCP ist es egal ob vom µC das SPI aktiv ist oder nicht, sobald sein
CS=low ist sein SPI-Interface aktiv.
Wenn du jetzt während PB4=L an SCK irgendwas ausgibst, da kannst du den
MCP schon irgendwelche Daten reinschieben, außerdem geht nach 7-8
Flankenwechseln an SCK auch Dout in den aktiven Zustand und verursacht
evl. einen Kurzschluss gegenüber MISO am µC wenn der auch auf Ausgang
steht. Hab gerade mal ins Datenblatt geschaut - nach CS=low muss dieses
für mind. 475ns wieder high sein sonst gibst sicher Probleme, aber die
Zeit wirst du sicher erreichen.
Es bleibt als sichere Lösung nur die CS-Leitung auf keinen Fall doppelt
zu belegen.
Sascha