Hallo Leute, ich wollte mal fragen ob mir jemand einen Quellcode schicken kann den ich in WinAVR in der Programmiersprache c/c++ einsetzen kann um den ad-Wandler anzusprechen bzw die werte auszulesen. Habe schon einiges probiert aber kenne den genauen Quellcode nicht. Für jede Antwort danke ich im vorraus! mfg Fuzzy
Habe ich schon klappt aber nicht. Kriege keine Werte aus den ADC heraus! Hier mein Quellcode als Anhang!!
Nimm für Deine Variable "x" besser einen unsigned int. Da kommen eh nur positive Werte rein. Bei signed-Variablen kann bei Schiebe-Operationen alles Mögliche passieren, je nachdem, was der Compiler draus macht.
>Nimm für Deine Variable "x" besser einen unsigned int. Genau. Und dann machst du nicht > x = ADCL; > x += (ADCH<<8); sondern x = ADC;
Hallo x = ADC; Ist immer gut! Wenn man die Register in der falschen Reihenfolge ausliest kommt nämlich nur Müll raus. Hat mich einmal einen halben Tag gekostet dem auf den Grund zu gehen. Habe ein Tutorial verwendet und da stand es verkehrt rum drinnen. Erst nach Blick ins Datenblatt ist mir dies dann aufgefallen,... Daher wer Probleme vermeiden will liest am besten gleich das ganze 16 Bit Register aus und überläst GCC die Details. LG Michael
Hallo Ich verwende ADC Funktionen auch mit Differential-Eingänge und deswegen ist Ruckgabewert signed int. Sogar ist Zeitverzögerung von 125µS(Datenblatt,Changing Channel or Reference Selection)bei umschalten von Singel-Ended auf Differential-Input mitberücksichtigt. Damit sind auch solche Konstruktionen problemlos möglich: … x=read_adc(2); //ADC 2, Single Ended y=read_adc(9); //Diff-Input ADC0-ADC1; Gain 10 Grüß Branko
@Branko: Das ist der unübersichtlichste (dafür aber universellste) Code, den ich seit langem gesehen habe. (ob der einem Anfänger hilft, bezweifle ich aber sehr).
Hallo Branko ich habe gerade ausprobiert dein Programm zu benutzen. Aber es klappt leider nicht Er gibt folgende Fehlermeldungen aus: adc.c: In function `read_adc': adc.c:188: error: `B_ADC_VREF_TYPE' undeclared (first use in this function) adc.c:188: error: (Each undeclared identifier is reported only once adc.c:188: error: for each function it appears in.) adc.c: In function `adc_init': adc.c:251: error: `B_ADC_VREF_TYPE' undeclared (first use in this function) adc.c:254: error: `B_ADC_PRESCALER' undeclared (first use in this function) Die Header-Datei habe ich in den Ordner in dem das C-Programm steht eingefügt. Ist das überhaupt richtig? Des weiteren lese ich über den AD-Wandler einen Potiwert ein (nur zur Info). Wie erkenne ich die Pins und Ports in dem Programm? vielleicht benutze ich einfach die falschen Pins? Kann ich das Programm überhaupt für meinem atmega16 benutzen? Fragen über fragen!!! Für hilfreiche Tipps danke ich im vorraus!! mfg Fuzzy
MANN FUZZY Wieso gehtst Du nicht zu diesem Link und kopierst den Beispiel Code? Oder noch besser vergleichst den Code mit deinem ? http://www.mikrocontroller.net/articles/AVR-GCC-Tu... Die Library von Branko würde ich ers mal verwenden wenn ich die Basisfunktionalität verstanden habe. ansonsten würde ich nur mal zum test folgendes im c file einfügen (ohne mir den code angesehen zu haben). bool B_ADC_PRESCALER=0; bool B_ADC_VREF_TYPE=0; LG Michael
@Fuzzy Hast du Headerfile auch ins Hauptprogramm inkludiert? #include<avr/io.h> #include "adc.h" int main (void) { adc_init(); // ADC initialisieren .... und in Makefile auch eingefügt? # MCU name MCU = atmega16 # Target file name (without extension). TARGET = ADC_AVR # List C source files here. (C dependencies are automatically generated.) SRC = $(TARGET).c adc.c Bei ATmega16 sind ADC Eingänge(DIP40): PIN ADCIN 40 ADC0 39 ADC1 38 ADC2 .. 33 ADC7 32 AREF 32 GND 31 AVCC //Mit VCC verbinden! und benützt wird einfach mit: x=read_adc(0) // Spannung von PIN40(ADC0) y=read_adc(1) // Spannung von PIN39(ADC1) .. z=read_adc(7) // Spannung von PIN33(ADC7) d=read_adc(16) // Spannungsdifferenz zwischen ADC0 und ADC1
Hab jetzt schon einiges probiert, und was ist das Resultat?!?? Der ATmega16 macht nichts mehr und sein Nachfolger der ATmega32 auch nicht!!! Hier der Quelltext. Da ist doch alles richtig?? Versteht´s nicht??? #include <avr/io.h> #include <inttypes.h> uint16_t readADC(uint8_t channel) { uint8_t i; uint16_t result = 0; // Den ADC aktivieren und Teilungsfaktor auf 16 stellen ADCSRA = (1<<ADEN) | (1<<ADPS2); // Kanal des Multiplexers waehlen ADMUX = channel; // Interne Referenzspannung verwenden (also 2,56 V) ADMUX |= (1<<REFS1) | (1<<REFS0); // Den ADC initialisieren und einen sog. Dummyreadout machen ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); result = ADCW; // ADC wieder deaktivieren // ADCSRA &= ~(1<<ADEN); PORTB=result; return result; } int main(void) { for(;;){ uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0, // also ADC0. In result steht das Ergebnis. return 0; } } Hab da noch ne Frage muss ich ADCSRA &= ~(1<<ADEN); überhaupt verwenden??? Hoffe, es kann mir jemand helfen!!!! mfg Fuzzy
Hallo Das return 0 würde ich aus der for Schleife nehmen, sonst mißt Du nur ein mal. Sonst konnte ich auf die Schnelle keinen Fehler finden. Das ist super schlechter Stil: while(ADCSRA & (1<<ADSC)); result = ADCW; Bitte gewöhn Dir das erst gar nicht an. Besser so: while(ADCSRA & (1<<ADSC)) { ; } result = ADCW; Besonders die Einrückung der Zeile result = ADCW; ist Fatal, da glaubt man schnell die gehört zu er while Schleife. So eine Geschichte kann Dir Stunden des Debuggens kosten. LG Michael
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.