Hey, Ich versuche einen 10bit ADW mit meinem MCU über den SPI auszulesen. Ich weiß, dass ich ihm erst 8bit schicken muss damit er wandelt. Dann kann ich mit nem schreiben einer 0 auf das SPDR die ersten 8bits abholen und mit einem erneuten schreiben einer 0 auf SPDR die 2. 8 bits. So weit so gut, denn das Ding zeigt mir immer nur 11111111 11111111 an. Das kann garnicht sein denn im Datenblatt heisst es: Das Ergebnis kommt mit einer "leading zero". Ich hab das ganze im AVR Studio noch mal simuliet und da ist mit aufgefallen, dass dach dem ich SPDR=0; gesetzt habe, das SPDR im nächsten Takt wieder den vorrangegangenen wert annimmt. Ist das normal? ist das der Fehler? oder kann mir jemand sagen wo hier der Fehler liegt?? Ich hänge hier noch mal meinen code dran.... int read_max(void) { unsigned int ReHigh, ReLow, tot; spi_on(); ----------(/SS = 0) _delay_us(100); SPDR=0xae;-------(code für den AD: Kanal 4, eigener Takt) loop_until_bit_is_set(SPSR, SPIF); ReHigh=SPDR; _delay_ms(100); SPDR=0; !!!! Nach diesem Befehl nimmt SPDR wieder den vorrangegangenen Wert an!!! loop_until_bit_is_set(SPSR, SPIF); ReHigh=SPDR; _delay_us(100); SPDR=0; loop_until_bit_is_set(SPSR, SPIF); ReLow=SPDR; _delay_us(100); spi_off(); tot=(unsigned int)((ReHigh*256+ReLow)/8); return tot; } Wäre super wenn mir jemand helfen könnt ich bin hier am verzweifeln!! MfG loki
> das SPDR im nächsten Takt wieder den vorrangegangenen wert > annimmt. SPDR Lesen und SPDR Schreiben sind zwei völlig verschiedene Dinge. Bist du dir sicher, dass du den korrekten SPI-Mode benutzt? Es gibt 4 verschiedene Varianten, wie man das Ruhepotenzial von SCK und die Taktflanken miteinander kombinieren kann.
Wenn die Flanken des Taktes CPOL sind dann sind die schon vom ADW vorgegeben. Im Datenblatt steht drin wie ich die einstellen muss. Wie ist das genau mit diesen 4 verschiedenen Einstellunge? Hab keinen Plan davon. Ich weiß dass ich schreibe mit SPDR=0x00 und lese mit ReLow=SPDR. ist denn das so richtig? Ich bin so frustriert gerade und MAN ich muss das Ding bis morgen fertig haben und es will nicht. Für Hilfe wäre ich mehr als dankbar loki
Register weiss ich gerade net aus dem Kopf, aber die beiden Bits weiss ich noch. ?? |= (1<<CPHA) | (1<<CPOL) Schau mal ins Datenblatt zum AVR. In dem Db stehen alle 4 Modis mit Timing Model.
Hatte durch Zufall noch einen Code fuer einen SPI AD Wandler hier, vielleicht hilft der weiter:
1 | #include <avr/io.h> |
2 | |
3 | // Mega16 Pinout
|
4 | #define MOSI 4
|
5 | #define MISO 6
|
6 | #define SCLK 7
|
7 | #define SS 4
|
8 | |
9 | |
10 | |
11 | unsigned int get_adc(unsigned char adata) |
12 | {
|
13 | static unsigned int temp=0; |
14 | |
15 | PORTB &= ~(1<<SS); // set cs on low to activied the adc |
16 | // maybe here a little delay
|
17 | SPDR = adata; // put the data into send register |
18 | while(!(SPSR & (1<<SPIF))); // send 1 Byte over HW SPI and wait for tx complete int |
19 | temp = SPDR; // put the received data to a static temp variable |
20 | temp = temp << 8; // shift the temp variable 8 steps left |
21 | SPDR = adata; // put the data into send register |
22 | while(!(SPSR & (1<<SPIF))); // send 1 Byte over HW SPI and wait for tx complete int |
23 | temp |= SPDR; // put the received data to a static temp variable |
24 | PORTB |= (1<<SS); // set cs on high to disable the adc |
25 | return temp; // return the adc value |
26 | }
|
27 | |
28 | |
29 | |
30 | void spim_init(void) |
31 | {
|
32 | // SET the Ports to output
|
33 | DDRB |= (1<<MOSI) | (1<<SCLK) | (1<<SS); |
34 | // SET MISO to input
|
35 | DDRB &= ~(1<<MISO); |
36 | // SPI Enable, SPI Master, SPI CLK XTAL/16, LSB First
|
37 | SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); |
38 | PORTB |= (1<<SS); // CS High because the SPI ADC is low active |
39 | }
|
40 | |
41 | int main (void) |
42 | {
|
43 | static unsigned int adc_value=0; // uint variable |
44 | |
45 | spim_init(); // Init HW SPI Master |
46 | adc_value = get_adc(0xFF); // Get data from SPI ADC send anything to generate the clock |
47 | |
48 | for(;;){} |
49 | }
|
Super..... Danke für den Code ich versuch ihn mal. Die 2 Bits (CPHA und CPOL) sollen laut Datenblatt vom ADW (Max147) auf low liegen. Was das bewirkt keinen Plan aber ich denk mal wenn das da so drin steht dann mach ich das doch mal so..... Ach man das mit dem Timing und dem Clock ding ist do was wie chinesisch für mich´. So ich schau mal was dein Code macht und meld mich dann noch mal. Danke noch mal loki
Dieser ADW ist ein bescheidenes DING!! Man der funst einfach nicht. Ich bekomme immer noch nur 11111111 11111111 Mehr will der einfach nicht ausspucken. Ich frag mich nur warum der nur einser ausspuckt! Da muss es doch nen Grund für geben. Noch ne Frage: Was ist das denn mit dem Buffer? Und woher weiß der MCU dass ich sein SPDR ausgelesen habe und er jetzt bitte das Verzeichniss löscht und was neues rein schreiben soll? Hat der da irgendein Register für? Oder wie kann ich denn den Puffer löschen? Mein Problem ist denke ich mal dass immer wenn ich ne neue 1 in den ADW reintackte dieser wieder neu wandelt und im ersten Byte bekanntlich nur Mist ausgibt. Ich steh grad voll auf dem Schlauch!! und irgendwie ist alles was mal so klar war in nem Wust untergegangen!!! Loki
Nur einsen 11111111 oder 0xFF bekommt ich am SPI auch wenn die verdahtung nicht stimmt. nimm mal ein oszi zur hand und schau was genau am ADC kommt. oder haeng den ADC mal ab und leg die MISO leitung auf ground. dann muesstest du 0x00 empfangen. somit kannst du wenigstens den fehler etwas weiter eingrenzen.
Hallo Zusammen, vielleicht ist das nicht relevant, aber wenn ich die aller ersten Codesequenz nachvollziehe, dann hast du zwei Delayzeiten eingebaut...
1 | .....
|
2 | _delay_us(100) |
3 | ....
|
4 | ...
|
5 | _delay_ms(100) |
Ich bin mir gerade nicht ganz sicher, aber wenn Du die Standard _delay_xx Funktion von AVR-Studio genommen hast, dann kann es sein, dass Deine Zeiten nicht stimmen. Denn ich meine man kann nur eine delay-Zeit bis 32ms definieren. Falls Du den Code von Dirk einfach so genommen hast, ohne die Zeiten einzubringen und der AD-W ist ein bißchen langsamer, dann ist er mit er Wandlung noch nicht fertig. Probiers das mal!! Gruß Benjamin
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.