Empfangen über SPI von ADC-Daten

OP #4076927
Hallo,
ich habe folgendes Problem:
Ich möchte mit einem ATmega128 von einem ADC (LTC2452) über SPI 
Messwerte einlesen.
Dabei verwende ich folgende Funktion zum empfangen eines Bytes:
1
uint8_t SPI_receive_byte()  // Byte empfangen
2
{
3
  SPDR = 0;    // Wert in Buffer speichern
4
  while(!(SPSR)&(1<<SPIF));
5
        // warten bis Zeichen verfügbar (Übertragung fertig)
6
  return SPDR;          // empfangenen Wert zurückgeben
7
}
Von dieser Funktion erhalte ich jedoch keinen Rückgabewert, laut 
Oszilloskop gibt der ADC aber Werte aus.
Laut Datenblatt müssen zwei Byte für eine vollständige Übertragung 
empfangen werden.
Vielen Dank im Vorraus
OP
Vielen Dank für die schnelle Antwort Holger!

Aber leider konnte ich das Problem dadurch nicht beheben.
Es kann doch nicht so schwer sein, als Master Daten über das SPI zu 
empfangen. (das Senden an DigiPots funktioniert ja auch)

Der ATmega scheint einfach keine Daten annehmen zu wollen. Hat irgendwer 
noch eine andere Idee?
OP
Hallo Frank!

Ja, richtig angeschlossen, durchgepiepst und mit dem Oszilloskop auf 
beiden Seiten des Busses gemessen.
ATmega <-> ADC
SCK    -> SCK
Enable -> /CS
MISO   -> SDO (serial data out)
(MOSI gibt's nicht)
-----
Die CLK-Rate des ADC geht bis 2MHz und ist auf 1MHz eingestellt.
Polarität und Mode passt auch.
-----
hier etwas mehr Code:
1
void spiInit(void) //Datasheet pg. 162
2
{
3

4
  DDRB |= ((1<<PB5)|(1<<PB7));    // MOSI, SCK => Output
5
  DDRB &= ~(1<<PB6);              // MISO => Input
6

7
  DDRD |= ((1<<PC0));             //ADC SS-Pin => Output
8

9
  SPCR |= ((1<<SPE)|(1<<MSTR)|(1<<SPR0)); // SPI enable, Master, f/16 
10
  SPCR |= (1<<CPOL);      // CLK mit falling Edge beginnen
11
  SPCR |= (1<<CPHA);      // Sample auf Trailing-Edge
12
}
13

14
uint16_t SPI_receive_ADC()  
15
{
16
  cli();      // Interrupts deaktivieren
17
  PORTC |= (1<<PC0);  // ADC Enable aus
18
    PORTC &= ~(1<<PC0);  // Enable-Pin für ADC aktivieren
19

20
  uint16_t averageData = 0;    
21
  averageData = (SPI_receive_byte()<<8);
22
  averageData |= SPI_receive_byte();
23

24
  PORTC |= (1<<PC0);  // ADC Enable aus
25
  sei();      // Interrupts aktivieren
26
  return averageData;
27
}
28

29
uint8_t SPI_receive_byte()  // Byte empfangen
30
{
31
  SPDR = 0x00;            // Wert in Buffer schreiben
32
  while(!(SPSR&(1<<SPIF)));  // warten bis Übertragung fertig
33
  return SPDR;        // empfangenen Wert zurückgeben
34
}
OP
Zwar schon etwas spät für eine Antwort, aber falls es zufällig jemanden 
interessiert:
Offensichtlich hatte ich zu irgendeinem Zeitpunkt am ATmega den MISO Pin 
als Output gesetzt und HIGH drauf geschrieben. Gleichzeitig hat mein 
SPI-Slave ein LOW an seinem MISO Pin gesetzt.
Somit hatte ich einen Kurzschluss zwischen ATmega und Slave und der AVR 
hat zuerst schlapp gemacht. Als ich einen neuen Chip eingelötet habe hat 
wieder alles funktioniert.

Ich kann also nur jedem raten, den MISO Pin seines ATmegas mit einem 
100ohm Widerstand gegen Kurzschlüsse abzusichern..

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.