Hallo Leute,
im Moment versuche ich mit einem ATmega16 über SPI den A/D-Wandler
ADS7841 auszulesen.
A/D-Wandler:
http://focus.ti.com/lit/ds/sbas084b/sbas084b.pdf
Controller:
http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
Die SPI-Schnittstelle des ATmega16 funktioniert, nur antwortet der
A/D-Wandler nicht wie erwartet.
Im Moment sind drei der Kanäle offen und am Vierten liegen ca. 2,5 V an,
trotzdem liefert der A/D-Wandler den Wert 0xFFF, also das Maximum
zurück. Die Eingangsspannung kann ich variieren wie ich will, an der
Ausgabe ändert sich nichts.
Gestern habe ich noch einen interessanten Effekt bemerkt. Wenn ich
meinen Finger auf die Eingangspins lege, dann ändert sich auch die
Antwort des A/D-Wandlers, die ich auf dem Oszilloskop beobachte.
Die Referenzspanung liefert eine 4,096 V-Referenzspannungsquelle. Die
restliche Schaltung siehe Anhang.
Könnte es sein, dass der A/D-Wandler defekt ist und kann ich das
irgendwie testen?
Nachfolgend noch der relevante Quellcode.
Alle möglichen Kombinationen aus CPOL, CPHA und DORD habe ich schon
durchprobiert. Vernünftige Ergebnisse erhalte ich in keinem der Fälle.
Bin über jede Hilfe dankbar.
Gruß
Rainer
1 | while(1)
|
2 | {
|
3 | if ( timer500ms_flag == 1) // wird von Timer gesetzt
|
4 | {
|
5 | timer500ms_flag = 0;
|
6 |
|
7 | SS_ADC_LOW;
|
8 |
|
9 | // Aufbau des Befehlsbytes: |Startbit|A2|A1|A0|MODE|SGL/DIF|PD1|PD0|
|
10 | // Startbit: muss immer 1 sein
|
11 | // A2..A0: Wahl des Kanals
|
12 | // MODE: 12bit oder 8bit
|
13 | // SGL/DIF: Single-Ended Channels wenn high
|
14 | // PD1..PD0: Engergiesparmodus
|
15 |
|
16 | //Kanal 0
|
17 | spi_send_byte(0x94); // Befehlsbyte an den ADC senden -> 0b10010100
|
18 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
19 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
20 |
|
21 | //Kanal 1
|
22 | spi_send_byte(0xD4); // Befehle an ADC senden
|
23 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
24 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
25 |
|
26 | //Kanal 2
|
27 | spi_send_byte(0xA4); // Befehle an ADC senden
|
28 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
29 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
30 |
|
31 | //Kanal 3
|
32 | spi_send_byte(0xE4); // Befehle an ADC senden
|
33 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
34 | spi_send_byte(0x00); // Dummydaten an ADC senden
|
35 |
|
36 | SS_ADC_HIGH;
|
37 | }
|
38 | }
|
39 |
|
40 |
|
41 | void spi_init (void)
|
42 | {
|
43 |
|
44 | DDRB |= (1<<PB5); //MOSI als Ausgang
|
45 | DDRB |= (1<<PB7); //SCK als Ausgang
|
46 | DDRB |= (1<<PB4); //SS als Ausgang
|
47 |
|
48 | SPCR = 0xD3; // SPI Interrupt enable, SPI enable, Master, f_osc/128 = 28,8 kHz
|
49 | }
|
50 |
|
51 |
|
52 | void spi_send_byte (unsigned char spi_byte)
|
53 | {
|
54 | SPDR = spi_byte;
|
55 |
|
56 | while(!(SPSR & (1<<SPIF)))
|
57 | {
|
58 | // warten bis Übertragung fertig ist
|
59 | }
|
60 | }
|