Hallo Leute,
ich wollte heute bzw. auch schon gestern, einen ADC an meinen ATMEGA8515 
anschließen. Und zwar möchte ich die SPI Schnittstelle dafür nutzen. 
Anscheinend ist das aber schwerer als gedacht.
Also ich habe einen ADC0831 (Datenblatt im Anhang)), das ist ein 
normaler analog - digital Converter, der die digitalen Daten seriel 
sendet. Folgende Verbindungen habe ich hergestellt:
ADC:              PORT B:
CS                PB0
CLK               PB7 (SCK)
Data out          PB6 (MISO)
Dann bekommt der ADC noch VCC und Masse von meinem STK 500 und außerdem 
habe ich die Referenzspannung des ADCs auf VCC gesetzt. Der Vin(-) 
Eingang des ADCs liegt auch auf Masse. Die zu messende / wandelnde 
Spannung liegt am ADC an Vin(+) an.
Der Code, mit dem ich die SPI Schnittstelle anspreche und den ADC Wert 
abfrage sieht wie folt aus:
1  | #define ADC_PORT     PORTB
  | 
2  | #define ADC_PIN      PINB
  | 
3  | #define ADC_DDR      DDRB
  | 
4  | #define ADC_CS       SBIT( ADC_PORT, 0)
  | 
5  | #define ADC_CS_DDR     SBIT( ADC_DDR, 0)
  | 
6  | #define ADC_CLK     SBIT( ADC_PORT, 7)
  | 
7  | #define ADC_CLK_DDR           SBIT( ADC_DDR, 7)
  | 
8  | #define ADC_MISO     SBIT( ADC_PIN, 6)
  | 
9  | #define ADC_MISO_DDR           SBIT( ADC_DDR, 6)
  | 
10  | 
  | 
11  | unsigned char adc_read (void);
  | 
12  | 
  | 
13  | int main (void){
 | 
14  | 
  | 
15  |   volatile unsigned char adc_wert = 0;
  | 
16  |   
  | 
17  |   ADC_CS_DDR     = 1;
  | 
18  |   ADC_CS      = 1;
  | 
19  |   ADC_CLK_DDR           = 1;
  | 
20  |   ADC_MISO_DDR          = 0;
  | 
21  |   ADC_MISO    = 0;
  | 
22  |   
  | 
23  |   SPCR |= (1<<SPE) | (1<<MSTR) | (1<<SPR0) | (1<<DORD);
  | 
24  |   SPCR &= ~((1<<CPOL) | (1<<CPHA));
  | 
25  |   DDRD = 0xFF;
  | 
26  | 
  | 
27  |   while(1){
 | 
28  |       adc_wert = adc_read();
  | 
29  |       PORTD = ~adc_wert;
  | 
30  |       
  | 
31  |     }
  | 
32  |   
  | 
33  |   return 0;
  | 
34  | }
  | 
35  | 
  | 
36  | unsigned char adc_read (void){
 | 
37  |   SPDR = 0x00;
  | 
38  |   ADC_CS = 0;
  | 
39  |   while ( !(SPSR & (1 << SPIF)) );
  | 
40  |   ADC_CS = 1;
  | 
41  |   return SPDR;
  | 
42  | }
  | 
Okay, wie man nun leicht sieht,  möchte ich einfach den Wert des ADCs 
auslesen und an PORTD des STK500 ausgeben. Ich habe da die LEDS 
angeschlossen, deshalb soll er den adc_wert nochmal invertieren, damit 
die LEDS bei einer Spg. von 0 alle auch aus sind und bei einer Spg. von 
Vin(+) = Vref sollen alle LEDs leuchten.
Ich weiß nun wirklich nicht mehr weiter, und habe mich auch schon 
totgesucht hier im Forum, aber anscheinend ist es total banal eine ADC 
an die SPI Schnittstelle anzuschließen, dass niemand damit 
Schwierigkeiten hat. Nun gut ich habe sie smile!
Also Mein ADC macht irgendwas ... nur nicht das was er soll. Gebe ich 
auf den Vin(+) Pin des ADCs die halbe Vref Spannung so müsste ja 
eigentlich 127 in SPDR bzw. an meinen LEDs zu finden sein, das ist 
leider nicht so. Er macht ne 5. So zieht sich das egal bei welcher 
Messung auch immer durch.
Auffällig ist, dass wenn ich den Vin(+) Pin des ADCs auf Masse lege, 
dass er eine 1 anzeigt. Bei Vin(+) = Vref zeigt er auch nicht 255 
sondern nur 253 an.
Kann das alles irgendwas damit zutun haben, dass die Programmierung 
meines Atmega8515 ja über das ISP des STK500 gemacht wird und das sich 
da irgendwas beeinflusst??
Wenn ich nämlich nachdem die Programmierung beendet ist, den ISP Stecker 
abziehe, dann verändert sich der gewandelte Wert um -1.
Sprich, wenn ich nun Vin(+) an Masse lege wird aus der vorher 
gewandelten 5 eine 4.
Weiterhin habe ich das ganze Programm mal Simuliert mit dem AVR Studio. 
Dabei ist mir aufgefallen, dass an der Stelle wo diese Zeile steht:
1  | while ( !(SPSR & (1 << SPIF)) );
  | 
Im zweiten Durchgang das Write Collision Flag gesetzt ist. Laut 
Datenblatt heißt das doch, dass gerade Daten in SPDR geschrieben werden, 
während einer Übertragung. Das hört sich für mich so negativ an!! Aber 
das ist doch richtig oder nicht?? So lange die Übertragung läuft ist 
doch das SPIF Bit auf 0 und Daten werden ins SPDR geschrieben (also muss 
doch das Write Collision Flag angehen), wenn die Übertragung nun fertig 
ist, steht im SPIF ne 1 und er bricht die Schleife ab und schaltet den 
ADC aus und gibt das SPDR zurück.
Ich versteh einfach nicht was falsch ist.
Kann es sein, dass mein ADC irgenwie defekt ist??? Oder meint ihr das 
Problem hat eher was mit der Konfiguration der SPI Schnittstelle zu 
tun??
Ich hoffe ihr könnt mir helfen!!
MfG BlueMorph