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?
Eine eigene Frage?
Dieser Thread ist über 15 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.