Forum: Mikrocontroller und Digitale Elektronik Problem: ADC Wert mittels SPI einlesen


von Dominik W. (absurdum)


Lesenswert?

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
unsigned char spi_ReWr(unsigned char byte)
2
{
3
  SPDR = byte;
4
  while(!(SPSR & (1 << SPIF)));
5
  return SPDR;
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?

von Dominik W. (absurdum)


Lesenswert?

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)?

von Sascha W. (sascha_w)


Lesenswert?

hast du auch CS (PB4) dekativiert wenn dein SPI aus ist, sonst bekommt 
der MCP3302 eine Taktflanke wenn du was an die LED's ausgibst.

Sascha

von Dominik W. (absurdum)


Lesenswert?

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?

von Sebastian (Gast)


Lesenswert?

Hallo!

Ich kann leider selbst bei der Problemlösungsfindung nicht weiterhelfen. 
Allerdings verstehe ich das hier nicht:
1
unsigned char spi_ReWr(unsigned char byte)
2
{
3
  SPDR = byte;
4
  while(!(SPSR & (1 << SPIF)));
5
  return SPDR;
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

von Dominik W. (absurdum)


Lesenswert?

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.

von Sascha W. (sascha_w)


Lesenswert?

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

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.