Hallo leute, folgendes Problem: ich möchte von einem 16Bit ADC (AD977A) Datenempfangen. Dieser hat eine Art "halbes" SPI... D.h. er wird vom MCU (ATMega32-->Master) geklockt, und der ATMega empfängt mit MISO. Die 16bit möchte ich auslesen in dem ich jeweils imner ein 8bit paket sende und direkt wieder auslese. Und das ganze 2mal hintereinander, wegen 16bit Wortbreite. So bekomme ich aber für conv_data_H immer nur dasselbe heraus und höchst unterschiedl. Wert für die gleichen Eingangsspannungen am ADC. Kann das so überhaupt funktionieren, was sagt ihr?? #include <avr/interrupt.h> #define F_CPU 8000000 #include <avr/io.h> #include <util/delay.h> ISR(INT2_vect) //Conversion finished { cli(); uint8_t conv_data_H, conv_data_L; conv_data_H = 0; conv_data_L = 0; PORTB |= (1<<PB7); //Set SCK output PORTB &= ~(1<<PB6); //SET MISO input PORTB |= (1<<PB5); //SET MOSI Output(wird hier nicht //gebraucht Pin hängt in der Luft) SPCR = (1<<MSTR)|(1<<SPR0) | (1<<SPR1); /* Enable SPI, Master, set clock rate fck/128 */ SPCR |=(1<<CPHA); //CPOL = 0, CPHA = 1 SPCR |= (1<<SPE); //SPI_enable SPDR = 0xF0; conv_data_H = SPDR; while(!(SPSR & (1<<SPIF))); SPDR = 0xF0; conv_data_L = SPDR; sei(); } int main() { cli(); GICR|=(1<<INT2); //INT2 ist Trigger für |Busy, steig. flanke MCUCSR |= (1<<ISC2); //INT2(PB2) ein! DDRB = 0b10100000; // PORTB |= ( 1<<PB0); //START_conv 1x DummyConversion PORTB &= ~(1<<PB0); PORTB |= ( 1<<PB0); _delay_ms(1); sei(); //Interupts an PORTB &= ~(1<<PB0); PORTB |= ( 1<<PB0); while(1) { ; } } Ist der Ansatz Prinzipiell richtig?
Gast
#661444
Woher kennst du denn den Inhalt der Variablen conv_data_H, ~_L ? Die sind doch nur lokal in der ISR... ;) Im Datasheet gibt's die Kapitel "EXTERNAL DISCONTINUOUS CLOCK DATA READ AFTER CONVERSION ..." und "EXTERNAL DISCONTINUOUS CLOCK DATA READ DURING CONVERSION ..". Du willst scheinbar ersteres. In beiden Fällen kann CS an GND angeschlossen werden und mit R\C wird die Wandlung gesteuert: RC muss vor dem auslesen auf high. Das sieht soweit korrekt aus bei dir, ABER: - du brauchst kein cli()/sei() in der ISR - der AD-Wandler verträgt 15MHz SPI-takt, F_CPU/128 ist da bestimmt nicht notwendig/verlängert unnötig deine ISR - das SPIF flag ist nicht vom startweg gesetzt, sondern erst nach einer Übertragung, also besser grundsätzlich erst SPDR schreiben und danach auf das Flag warten - warum schreibst du das DAC-Ergebnis nicht gleich in eine 16Bit Variable (int, int16_t)? - Wenn du das Ergebnis in main() haben willst, musst du es dort hinbringen -> mit einer volatile globalen Variable hth Jörg, der Datenblattleser ;) ps.: wenn du noch mehr Probleme hast, poste bitte deine Schaltung (der ADC wird ja mit diversen Pins konfiguriert...)
Gast
#661465
Zusätzlich zu Jörg: >conv_data_H = 0; >conv_data_L = 0; Kannst du dir komplett sparen. Werden beim lesen von SPDR sowieso wieder überschrieben. PB4/SS wird nicht auf Ausgang geschaltet. Da wird der Master evtl. ganz schnell wieder zum Slave. >PORTB |= (1<<PB7); //Set SCK output >PORTB &= ~(1<<PB6); //SET MISO input >PORTB |= (1<<PB5); //SET MOSI Output(wird hier nicht //gebraucht Pin Das sollte wohl DDRB statt PORTB heissen. Hat in der ISR aber auch nichts zu suchen. Auch SPCR setzt man besser nicht in der ISR.
Gast
#661473
Achja, hab ich vorhin vergessen: nimm die ganze SPI-Register- und Port-Initialisierung aus der ISR! Da musst du meistens gar nichts machen, es sei denn du hast mehrere SPi-Slaves mit unterschiedlichen Modi bzw. Geschwindigkeiten. hth. Jörg
danke erstmal für die schnellen comments! es lag v.a. am nicht gesetzen |ss sollte nur ein test sein ob das überhaupt funzt. werde eure hints morgen umsetzen. gruß georg
Jörg X. wrote: > - warum schreibst du das DAC-Ergebnis nicht gleich in eine 16Bit > Variable (int, int16_t)? Weil SPDR nur 8bit breit ist, dachte ich! also, wenn ich das mit uint16_t auslese machen die werte wenig sinn, bzw. scheint so als würde er ein byte "abschneiden"... wie kann ich das denn direkt auslesen, oder warum sollte das überhaupt direkt funzen? mfg g.brfd
Gast
#661905
>wie kann ich das denn direkt auslesen,1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
hth. Jörg
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.