SPI Slave mit ATMega auslesen

Gast #2483378
Lesenswert?

Hi,

ich habe einen ATMega16 als SPI Master und einen ADC als Slave. Ich 
möchte den Slave jetzt über SPI auslesen. Hab ich das richtig 
verstanden, dass ich dazu etwas ins SPI Datenregister schreiben muss und 
so tue als würde ich das senden? Und dass beim Senden dann mein 
Datenregister gleichzeitig die Daten vom ADC am MISO Pin empfängt und 
einliest?

Ich hab folgenden Code im Datenblatt des ATMega gefunden und für meine 
Zwecke erweitert:
1
#define DD_MOSI PINB5
2
#define DD_MISO PINB6
3
#define DD_SCK  PINB7
4
#define DD_SS  PINB4
5
#define DDR_SPI DDRB
6
#define PORT_SPI PORTB
7

8
/* ADC initialisieren */
9
void ADC_Init(void)
10
{
11
  //SPI initialisieren
12
  /* Set MOSI, SCK and SS output, all others input */
13
  DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
14
  /* Enable SPI, Master, set clock rate fck/16 */
15
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
16
  
17
  //ADC deaktivieren
18
  PORT_SPI |= (1<<DD_SS);
19
}
20
 
21
/* ADC Einzelmessung */
22
uint8_t ADC_Read(void)
23
{
24
  //ADC aktivieren
25
  PORT_SPI &= ~(1<<DD_SS);
26
  
27
  /* Start transmission */
28
  SPDR = 1;
29
  /* Wait for transmission complete */
30
  while(!(SPSR & (1<<SPIF)))
31
  ;
32
  //ADC deaktivieren
33
  PORT_SPI |= (1<<DD_SS);
34
  /* Return data register */
35
  return  SPDR;
36
}

Leider kommt vom ADC jetzt immer der Wert 15, egal was ich an seinem 
Eingang anlege. Wie lese ich einen SPI Slave aus?
#2483429
Lesenswert?

1.:
Welchen ADC verwendest du?

2.:
Eine kleine Verallgemeinerung wie das Ganze bei deinem ADC funktionieren 
könnte:
Du kannst nicht einfach Messwerte auslesen.
Du musst den ADC zuerst initialisieren.
Dann gibt es spezielle Kommandos mit denen du z.B. eine Einzelmessung 
starten kannst oder den ADC dauernd messen lassen kannst.
Um die Messdaten dann auszulesen musst du auch ein bestimmtes Byte 
hinsenden (je nachdem was für einen ADC du hast) und dann bekommst du 
deine Messdaten zurück.
Gast #2483438
Lesenswert?

Also Initialisieren oder so muss man den nicht. Der hat auch nur eine 
Datenleitung für Data_out. Also Befehle senden oder so muss ich nicht. 
D.h. sobald ich SS aus low ziehe und SCLK sende, schickt er die Daten 
raus.
#2483631
Lesenswert?

Wenn du Hardware SPI des uCs verwendest kannst du nicht 20 Bit 
übertragen sondern musst auf 24 Bit erweitern.

Das heißt du musst 3 Bytes übertragen.

Als erstes bekommst du dann 4 Zero Bits dann kommen deine 16 Datenbits 
(ADC ergebnis) und dann kommen noch einmal 4 Zero Bits.

Dein Ergebnis musst du dir dann aus den 3 Bytes rausfischen (und in eine 
16Bit Variable schieben)

Für so eine Anwendung verwende ich meist eine Software Routine:
- 4 Clockpulse in einer Schleife erzeugen
- 16 Clockpulse in einer Schleife erzeugen und die Bits aufnehmen (in 
eine 16Bit variable)
- Schon hast du dein fertiges Ergebnis

Du kannst das ganze dann ganz einfach testen indem du den Eingang einmal 
auf Masse und einmal auf VDD hängst. Einmal solltest du dann lauter 0er 
bekommen und im anderen Fall solltest du lauter 1er bekommen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren