Hallo Leute, ich möchte gerne zwei Spannungswerte durchgängig mit Hilfe des AD-Wandlers des Atmega8 ausgeben. Mit einem Wert habe ich das auch so weit hinbekommen: // Interrupt-Routine: ... unsigned int result1 = ADCW; // Hierfür lese ich Kanal 4 ein: ... ADMUX = (1<<REFS0) | 4; Nun möchte ich einen weiteren Kanal einlesen. Aber den Wert kann ich ja nicht im ADCW Register speichern... Im Datenblatt des Atmega steht leider nichts über das ADCW Register. Hat jemand vielleicht eine Idee, wie ich das lösen kann? Vielen Dank und Gruß Micha
Michael schrieb: > Aber den Wert kann ich ja nicht im ADCW Register speichern... Aus diesem Register liest du ihn ja auch nur aus. Speichern musst du ihn in einer zweiten Variablen, also irgendwas anderes als "result1". > Im Datenblatt des Atmega steht leider nichts über das ADCW Register. Der Name ADCW ist nur ein Pseudonym für die Vereinigung von ADCL und ADCH. Normalerweise werden die Namen derartiger 16-bit-Pseudoregister einfach durch Weglassen von H bzw. L gebildet, aber da der sich hier ergebende Name ADC zugleich eine Assemblermnemonik ist (für "add with carry"), gibt es zusätzlich noch den Namen ADCW als Alias dafür, wobei bei der Benutzung von <avr/io.h> in einer Assemblerdatei nur dieser Name benutzbar ist.
Danke für die Antwort, Jörg. Jörg Wunsch schrieb: > Aus diesem Register liest du ihn ja auch nur aus. Speichern > musst du ihn in einer zweiten Variablen, also irgendwas anderes > als "result1". Wenn ich also eine zweite Variable definiere, kann ich die dann ebenfalls aus dem Register ADCW auslesen? z.B.: unsigned int result2 = ADCW; Dementsprechend muss ich in main-file folgendes hinzufügen: ADMUX = (1<<REFS0) | 3; also einen anderen Kanal einlesen. Ist das so richtig? Kann ich dann gleichzeitig in der Interrupt Routine auf beide Werte zugreifen?
Michael schrieb: > Ist das so richtig? Im wesentlichen: Ja Auch wenn ich mir nicht sicher bin, ob du das richtige meinst. > > Kann ich dann gleichzeitig in der Interrupt Routine auf beide Werte > zugreifen? Nein. Du hast im µC nur einen ADC. Dessen Eingang kannst du auf verschiedene Eingangspins schalten lassen und so unterschiedliche Eingänge messen lassen. Aber nur hintereinander! Denn ... es existiert nur 1 Analog Digital Konverter. Den Interrupt bekommst du, nachdem der ADC fertig gewandelt hat. Also nach einer Messung. Daher kannst du dort nicht 2 Eingänge abfragen, denn der andere Eingang wurde ja noch gar nicht vermessen. Darf ich fragen, warum du da überhaupt Interrupts benutzt? Mir scheint deine C-Kentnisse sind noch nicht so weit, dass ich dir eine saubere und korrekte Behandlung von Interrupts zutrauen würde. im AVR-GCC-Tutorial, im Abschnitt über den ADC gibt es fix fertige Routinen, die du nur benutzen musst. Und ich denke (ohne jetzt deine Anwendung zu kennen), dass du damit erst mal besser bedient wärst.
Karl Heinz Buchegger schrieb: > Darf ich fragen, warum du da überhaupt Interrupts benutzt? Ich benutze ein Interrupt nach abgeschlossener AD-Wandlung. Den Messwert lese ich aus dem ADCW Register aus, um damit weiter arbeiten zu können. (s.oben) Dies könnte ich aber auch in der main-Datei aufrufen. Mir ist nur wichtig, dass ich dann in der main-Datei folgendes aufrufen kann: int main() { uint16_t result1; uint16_t result2; ADC_Init(); while( 1 ) { result1 = ADC_Read(3); // Kanal 3 // mach was mit result1 result2 = ADC_Read(4); // Kanal 4 // mach was mit result2 } } Die Interrupts möchte ich verwenden, damit ich jeweils die aktuellen Werte für result1 und result2 erhalte. Werden diese Werte in der main-Datei denn aktualisiert oder nur einmal ausgelesen und dann gespeichert? Vielen Dank
Michael schrieb: > Karl Heinz Buchegger schrieb: >> Darf ich fragen, warum du da überhaupt Interrupts benutzt? > > Ich benutze ein Interrupt nach abgeschlossener AD-Wandlung. > Den Messwert lese ich aus dem ADCW Register aus, um damit weiter > arbeiten zu können. (s.oben) Das ist nicht die Frage. Die Frage war: WARUM Interrupts. Warum nicht einfach ganz normal pollen. > int main() > { > uint16_t result1; > uint16_t result2; > ADC_Init(); > > while( 1 ) { > result1 = ADC_Read(3); // Kanal 3 > // mach was mit result1 > > result2 = ADC_Read(4); // Kanal 4 > // mach was mit result2 > } > } > > Die Interrupts möchte ich verwenden, damit ich jeweils die aktuellen > Werte für result1 und result2 erhalte. Die hast du sowieso. In dem Moment, in dem du ADC_Read aufrufst, wird der angegebene Kanal gemessen. > Werden diese Werte in der main-Datei denn aktualisiert oder nur einmal > ausgelesen und dann gespeichert? Bei jedem Aufruf von ADC_Read findet eine Messung statt. Und zwar am angegebenen Kanal. Das ist nichts anderes als i = PINB; das wird auch jedesmal ausgeführt und der zum Zeitpunkt der Ausführung aktuelle Zustand der Portpins an i zugewiesen. Die ADC Funktionen sind so geschrieben, dass sie sich genau gleich verhalten. Davon kann man sich durch Studium der ADC_Read Funktionen aus dem Tut leicht überzeugen. Bei jedem Aufruf wird eine Messung angestossen und dessen Beendigung abgewartet.
Danke Karl, hast mir schon sehr weiter geholfen. > Die Frage war: WARUM Interrupts. > Warum nicht einfach ganz normal pollen. Damit ich eine kontinuierliche Messung, bzw. einen aktuellen Messwert erhalte, wollte ich einen interrupt verwenden. > Bei jedem Aufruf von ADC_Read findet eine Messung statt. Und zwar am > angegebenen Kanal. Der zu messende Wert in meiner Applikation ändert sich jedoch und muss ständig gemessen werden. Die Messung durch ADC_Read findet doch aber nur einmal statt oder sehe ich das falsch?
Michael schrieb: > Danke Karl, hast mir schon sehr weiter geholfen. > >> Die Frage war: WARUM Interrupts. >> Warum nicht einfach ganz normal pollen. > > Damit ich eine kontinuierliche Messung, bzw. einen aktuellen Messwert > erhalte, wollte ich einen interrupt verwenden. > > >> Bei jedem Aufruf von ADC_Read findet eine Messung statt. Und zwar am >> angegebenen Kanal. > > Der zu messende Wert in meiner Applikation ändert sich jedoch und muss > ständig gemessen werden. > Die Messung durch ADC_Read findet doch aber nur einmal statt oder sehe > ich das falsch? Welchen Teil des Satzes Bei jedem Aufruf von ADC_Read findet eine Messung statt. verstehst du 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.