Hallo Leute, ich setze mich im Moment mit ADC auseinander, zum größten Teil verstehe ich es, ich hätte jedoch trotzdem paar Fragen. Dieses Außenrum verstehe ich nicht. Das ist dieses Beispiel aus dem Tutorial: uint16_t ReadChannel(uint8_t mux) { uint8_t i; uint16_t result; ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler // setzen auf 8 (1) und ADC aktivieren (1) ADMUX = mux; // Kanal waehlen ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */ ADCSRA |= (1<<ADSC); // eine ADC-Wandlung while ( ADCSRA & (1<<ADSC) ) { ; // auf Abschluss der Konvertierung warten } result = ADCW; // ADCW muss einmal gelesen werden, // sonst wird Ergebnis der nächsten Wandlung // nicht übernommen. /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */ result = 0; for( i=0; i<4; i++ ) { ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" while ( ADCSRA & (1<<ADSC) ) { ; // auf Abschluss der Konvertierung warten } result += ADCW; // Wandlungsergebnisse aufaddieren } ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2) result /= 4; // Summe durch vier teilen = arithm. Mittelwert return result; } ... /* Beispielaufrufe: */ void foo(void) { uint16_t adcval; adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */ ... adcval = ReadChannel(2); /* MUX-Bits auf 0b0010 -> Channel 2 */ ... } Wenn ich es richtig verstanden habe, ist es wie eine Funktion aufgebaut, mit der Variable "mux" wird der analoge Pin übergeben, an dem gemessen werden soll, und in die Variable "ReadChannel" das Ergebniss der Messung an das eigentliche Programm. Ich bin mir aber gar nicht sicher weil ich so eine Schreibweise noch nicht gesehen habe "uint16_t ReadChannel(uint8_t mux)" Was haben die Klammern zusagen?? Muss ich "mux" eine Nummer zuweisen? (Welcher Pin)und in welcher Schreibweise 2 oder 0b00000010. Ich Verwende ein ATmega 32, habe ich es richtig verstanden dass man die Taktung von 0-16 MHz einstellen kann? Ich weis nicht wie der jetzt getaktet wird, wo finde ich es? dann muss ich doch auch den Frequenzvorteiler im ADCSRA verändern. Mit dem Quellcode von Oben funktioniert es noch nicht. Ich hoffe die Fragen sind nicht all zu doof und dass ihr einem Anfänger helfen könnt. (Wäre sehr nett)
> Wenn ich es richtig verstanden habe, ist es wie eine Funktion > aufgebaut, Nicht nur wie, das ist eine Funktion. > mit der Variable "mux" wird der analoge Pin übergeben, an dem > gemessen werden soll, Richtig. > und in die Variable "ReadChannel" das Ergebniss der Messung ReadChannel ist der Name der Funktion, die als Funktionswert das Ergebnis der Messung liefert. > uint16_t ReadChannel(uint8_t mux) ^ Name des Arguments ^ Typ des Arguments (8-Bit-Zahl ohne Vorzeichen) ^ Name der Funktion ^ Typ des Funktionswerts (16-Bit-Zahl ohne Vorzeichen) > Was haben die Klammern zusagen?? Die Klammern umschließen einfach die Liste der Funktionsargumente. > Muss ich "mux" eine Nummer zuweisen? (Welcher Pin)und in welcher Der Aufruf der Funktion sieht bspw. so aus:
1 | ergebnis = ReadChannel(3); |
Diese Anweisung führt eine Messung am Pin ADC3 durch. Führ dir doch mal ein C-Tutorial zu Gemüte, dann werden dir viele dieser Dinge klar werden. > Ich Verwende ein ATmega 32, habe ich es richtig verstanden dass man > die Taktung von 0-16 MHz einstellen kann? Es gibt verschiedene Möglichkeiten, den ATmega32 zu takten: Meist wird der interne RC-Oszillator oder der interne Quarzoszillator mit externem Quarz verwendet. Weitere Möglichkeiten stehen im Datenblatt unter "System Clock and Clock Options". Je nach verwendetem Oszillator stehen unterschiedliche Frequenzen zur Verfügung. Parametriert wird das Ganze über sogenannte Fuses (AVR Fuses). Die Fuses können auch ausgelesen werden, um festzustellen, was gerade eingestellt ist. Ein fabrikneuer ATmega32 ist so eingestellt, dass er durch den internen RC-Oszillator mit 1 MHz getaktet wird.
Super, DANKE SEHR ich glaube jetzt komme ich langsam dahinter, das ist eine Funktion der ein Wert übergeben wird, die aber auch ein Wert zurück liefert. Wie kann ich die Fuses auslesen?? Aber da es ein neuer Atmega 32 ist, gehe ich davon aus dass der mit 1MHz getaktet wird. Mit dem Wert habe ich mir den Teilungsfaktor von 5 bis 20 ausgerechnet und im ADC den Wert von 16 eingestellt. Leider funtioniert es immer noch nicht, es leuchtet warum auch immer die 2 LED (PORTC1), aber sonst pasiert nichts. Könnte mir einer bei der Fehlersuche helfen?? Das ist mein Quellcode Die Funktion "warte_ms" hat nichts zu sagen #include <avr\io.h> #include <inttypes.h> #include <stdint.h> // Funktionen void warte_ms(unsigned int Verzoegern); uint16_t ReadChannel(uint8_t mux); int main(void) { DDRC = 0b11111111; // Ausgänge am PORTC PORTC = 0b11111111; // LEDs Aus uint16_t adcval; adcval = ReadChannel(1); /* MUX-Bits auf 0b0001 -> Channel 1 */ if (adcval > 0) { PORTC= 0b00000000; // LEDs EIN } return 0; } //____________________Funktion ADC_______________________________________ uint16_t ReadChannel(uint8_t mux) { uint8_t i; uint16_t result; ADCSRA = (1<<ADEN) | (1<<ADPS2); // Frequenzvorteiler // setzen auf 16 (1) und ADC aktivieren (1) ADMUX = mux; // Kanal waehlen ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */ ADCSRA |= (1<<ADSC); // eine ADC-Wandlung while ( ADCSRA & (1<<ADSC) ) { ; // auf Abschluss der Konvertierung warten } result = ADCW; // ADCW muss einmal gelesen werden, // sonst wird Ergebnis der nächsten Wandlung // nicht übernommen. /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */ result = 0; for( i=0; i<4; i++ ) { ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" while ( ADCSRA & (1<<ADSC) ) { ; // auf Abschluss der Konvertierung warten } result += ADCW; // Wandlungsergebnisse aufaddieren } ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2) result /= 4; // Summe durch vier teilen = arithm. Mittelwert return result; } //__________Funktion___Wartezeit_in_ms______________ void warte_ms(unsigned int Zeitwert) //Lade Funktion "warte_ms" mit dem Wert Zeitwert { while(Zeitwert!=0) //Solange laufen bis Zeitwert Null ist { unsigned int j; //Variable "j" for(j=0;j<2000; j++) {asm("nop");} //Anfangswert=0 laufen bis 1000 mit jedem Durchlauf um 1 erhöhen Zeitwert--; //Wenn bei 1000 angekommen den Zeitwert um 1 reduzieren } }
Max wrote: > ich glaube jetzt komme ich langsam dahinter, das ist eine Funktion der > ein Wert übergeben wird, die aber auch ein Wert zurück liefert. Genau. Ist so wie x = sin( 25 ); sin ist eine Funktion namens Sinus. Sie bekommt einen Wert übergeben, macht irgendetwas damitund liefert wieder einen Wert. > Wie kann ich die Fuses auslesen?? Dein Brennprogramm hat irgendwo einen Menüpunkt dafür. Welches Programm verwendest du? > Aber da es ein neuer Atmega 32 ist, gehe ich davon aus dass der mit 1MHz > getaktet wird. Korrekt. > > Mit dem Wert habe ich mir den Teilungsfaktor von 5 bis 20 ausgerechnet > und > im ADC den Wert von 16 eingestellt. > > Leider funtioniert es immer noch nicht, es leuchtet warum auch immer die > 2 LED (PORTC1), aber sonst pasiert nichts. Nimm einen anderen Port. Auf PORTC liegen Sonderfunktionen, die Defaultmaessig aktiviert sind. Die kann man mit einer Fuse (JTAGEN) abschalten aber dazu musst du erst mal die Fuses lesen und schreiben können :-)
Ich verwende WinAVR Ich habe es jetzt mit PORTD und B probiert, es fuktioniert nicht. Wobei am B der Programeierstecker liegt. Hier ist was faul, ich habe jetzt genau andersrum probiert also so int main(void) { DDRD = 0b11111111; // Ausgänge am PORTC PORTD = 0b00000000; // LEDs EIN uint16_t adcval; adcval = ReadChannel(2); /* MUX-Bits auf 0b0000 -> Channel 0 */ if (adcval > 0) { PORTD = 0b11111111; // LEDs AUS } return 0; } Jetzt sollen die LEDs sofort angehen und wenn gemessen wurde und Wert >0 ist, wieder ausschalten. Die gehen aber nicht mal an.
So, die LEDs sind jetzt an (PORTD), der Analoge Wert kommt auch am PINA1 an, die Messung geht aber nicht.
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.