www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Free-Running and Compare Match A Auto-Triggering AD-Wandler


Autor: Sebastian O. (sebas)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das Ziel meiner Applikation ist die Messung von analogen Werte durch den 
AD-Wandler. Deswegen habe ich die zwei folgende Möglichkeiten 
ausgewählt:

1) Aktivierung des AD-Wandlers mit Auto-Triggering. Als Trigger-Quelle 
wird der "COMPARE MATCH A" des Timers 0 verwendet. Damit die Flag für 
COMPARE MATCH A wieder für die Aktivierung des AD-Wandlers verwendet 
werden kann, wird diese Flag durch die Interrupt-Aufruf gelöst.

- Hier habe ich zwei Probleme: die Flag für COMPARE MATCH A (OCF0A) wird 
nur manchmal gesetzt und der AD-Wandler wird nie aktiviert (ADSC=0).


2) Aktivierung des AD-Wandlers mit Auto-Triggering. Als Trigger-Quelle 
wird "Free-Running" verwendet. Damit der AD-Wandler starten werden kann, 
wird das Bit ADSC des Registers ADCSRA gesetzt in der Initialisierung 
des AD-Wandlers.

-Hier habe ich folgendes Problem: nach der ersten Konvertierung (die zu 
meinem Zeit-Design auch nicht passt) wird die Interrupt-Flag des 
Interrupts gesetzt und der AD-Wandler wird nie wieder aktiviert, da das 
Bit ADSC gelöst wird.

Ich wäre sehr dankbar, wenn jemand mir einen Vorschlag geben könnte.

Anbei die zwei "main" Dateien.

Viele Grüße,

Sebas

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ich wäre sehr dankbar, wenn jemand mir einen Vorschlag geben könnte.

Für beide Fälle: ADC-Complete-Interrupt verwenden.

MfG Spess

Autor: Rudi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>die Flag

die Flag != dis Flag
die Flag wird geschrieben auch mit "k"  und is (war) Kanone.
dis Flag ist im englischen ein "Fähnchen"

;) nicht ernst, bitte

Autor: Sebastian O. (sebas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

danke für die Rückmeldungen.


> Für beide Fälle: ADC-Complete-Interrupt verwenden.

Sollte die Konvertierung nicht automatisch starten?

1) Auto-Triggering mit Compare Match A: die Konvertierung sollte mit der 
Interruptserzeugung des Timers gestartet werden.

2) Auto-Triggering mit Free-Running: nachdem der AD-Wandler einmal 
gestartet wird, sollte der AD-Wander frei and kontinuierlich laufen.


Warum sollte die ADC-Complet-Interrupt aufgerufen werden?


Viele Grüeße,

sebas

PS: sorry, aber ich lerne Deutsch nur seit 2 Jahre. Deswegen ist meine 
Sprache nicht ganz richtig.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian O. schrieb:

> Ich wäre sehr dankbar, wenn jemand mir einen Vorschlag geben könnte.

Woher weißt du eigentlich so genau, welches Flag wann und warum nicht 
mehr gesetzt wird?
Ich rate mal: Aus dem Simulator

Dann lass dir gesagt sein, dass der Simulator so manches Problem hat und 
nicht alle Details des realen Chips korrekt nachbildet.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Warum sollte die ADC-Complet-Interrupt aufgerufen werden?

An irgend einer Stelle musst du den AD-Wert ja auslesen. Da bietet sich 
der Interrupt an. Und im 1.Fall kannst dort gleic das 
Timer-Interrupt-Flagzurück setzen.

MfG Spess

Autor: Sebastian O. (sebas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,


> An irgend einer Stelle musst du den AD-Wert ja auslesen. Da bietet sich
> der Interrupt an. Und im 1.Fall kannst dort gleic das
> Timer-Interrupt-Flagzurück setzen.

in beiden Fälle wird die Interrupt-Routine nie aufgerufen, obwohl das 
Bit ADIE vom Register ADCSRA gesetzt wird. Das bedeutet, dass der 
AD-Wandler läuft überhaupt nicht, aber ich verstehe das nicht.


Grüße
sebas

Autor: avion23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nicht lachen: sei() ?

Ich habe auch Probleme mit dem free running modus. Probier mal deine ISR 
ab zu specken, z.B. nur led togglen. Dann schauen, wie oft die led 
togglet.

Bei mir gibt es aktuell, dass der free running modus nur funktioniert, 
wenn ich jeden zweiten ADC-Wert verwerfe. Ich denke das liegt am channel 
wechsel (bei mir). Auch mal deaktiveren.

Wie debuggst du?

Autor: Sebastian O. (sebas)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

> nicht lachen: sei() ?

im Code für die Auto-Triggering mit Compare Match A hatte ich es schon. 
Der Interrupt für ADC wird nie aufgerufen.

Mit Free-Running wird die Routine nicht aufgerufen, aber es wird ein 
Reset erzeugt. Wieso denn? Sollte ich der Watchdog Timer ausschalten?

> Bei mir gibt es aktuell, dass der free running modus nur funktioniert,
> wenn ich jeden zweiten ADC-Wert verwerfe. Ich denke das liegt am channel
> wechsel (bei mir). Auch mal deaktiveren.

Ich verwende immer den gleichen Kanal (ADC3), so verstehe ich auch 
nicht, warum ich werte verwerfen muss.


> Wie debuggst du?

Ich debbuge mit Debugging von AVR Studio 4. Zurzeit habe ich die 
Leiterplatte noch nicht fertig. Deswegen simuliere ich nur.

Grüße,

Sebastian

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>in beiden Fälle wird die Interrupt-Routine nie aufgerufen, obwohl das
>Bit ADIE vom Register ADCSRA gesetzt wird. Das bedeutet, dass der
>AD-Wandler läuft überhaupt nicht, aber ich verstehe das nicht.

Ein kleines Testprogramm (Assembler) mit Autotrigger durch Timer0 läuft 
bei mir im Simulator problemlos.

MfG Spess

Autor: Sebastian O. (sebas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,


> Ein kleines Testprogramm (Assembler) mit Autotrigger durch Timer0 läuft
> bei mir im Simulator problemlos.


hast du mit meinem C-Code probiert?

Wäre es empfehlenswert, mit Assembler statt C zu programmieren?


Grüße,

Sebas

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>hast du mit meinem C-Code probiert?

Nein. Ich benutze kein C.

>Wäre es empfehlenswert, mit Assembler statt C zu programmieren?

Ehe grössere Dikussionen aufkommen: Nimm das, was du am besten kannst.

Bei dir hängt es allerdings nicht nur an der Programmiesprache.

MfG Spess

Autor: avion23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR (ADC_vect)
{
  ADCSRA &= ~(1<<ADIF);
  PORTB &= ~(1<<PB0);
  result = ADCH;
}
Warum nicht ADC abfragen an Stelle von ADCH? Ärger vermeiden:
When ADCL is read, the ADC Data Register is not updated until ADCH is read.
Consequently, if the result is left adjusted and no more than 8-bit 
precision is required, it is sufficient to read
ADCH. Otherwise, ADCL must be read first, then ADCH.
 Datenblatt attiny25

Kommentar in deinem Code, nicht nachgeprüft:
 // Prescaler=8(FADC=1MHz)
f_adc_max = 200kHz.

Bei mir gibt es im Code auch noch ein ADCSC, bei dir nicht. Ohne 
funktioniert es nicht
In Single Conversion mode, write this bit to one to start each 
conversion. In Free Running mode, write this bit to one to start the first 
conversion


UND: Im Simulator funktioniert der ADC nicht. Habe ich nicht selbst 
überprüft, aber an x Stellen gelesen.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>UND: Im Simulator funktioniert der ADC nicht. Habe ich nicht selbst
>überprüft, aber an x Stellen gelesen.

AVR Studio Hilfe:

Analog to Digital Converter (ADC)

Analog input is not supported. However, based on the ADC Prescaler 
Select bits (ADPS), the ADIF flag is set after the correct number of 
cycles. The ADC completion interrupt is also simulated correctly.
The ADC Data register (ADCH/ADCL) can be manually set e.g in the I/O 
view.

Zum Simulieren langt es. Im Simulator2 kannst du sogar über ein 
Stimuli-File ADCL/H auf bestimmte Werte setzen.

MfG Spess

Autor: Sebastian O. (sebas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
> Warum nicht ADC abfragen an Stelle von ADCH? Ärger vermeiden:

Weil es nur für meine Applikation notwendig ist. Wichtig ist es nur, ob 
der Eigang die Spannungsreferenz erreicht hat.


> Kommentar in deinem Code, nicht nachgeprüft:
>
 // Prescaler=8(FADC=1MHz)
> f_adc_max = 200kHz.

Es wird auch gesagt, dass für niedrige Auflösung eine Frequenz bis 1 MHz 
vewerdet werden kann.

> Bei mir gibt es im Code auch noch ein ADCSC, bei dir nicht. Ohne
> funktioniert es nicht
>
In Single Conversion mode, write this bit to one to start each
> conversion. In Free Running mode, write this bit to one to start the
> first
> conversion
>

In meinem Code wird folgendes geschrieben:
ADCSRA |= (1<<ADSC);
    // Start the conversion


Sorry, aber ich weiss nicht, was ich noch prüfen kann. Gibt es noch eine 
Stelle, die geprüft werden müsste?

Danke.

Autor: avion23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sebastian,
in deinem zweiten Code Abschnitt wird der ADC nicht gestartet. Darauf 
habe ich mich bezogen.

Was du noch tun kannst:
Ganz allgemein alle Fehlerquellen ausschalten. Also erstmal den normalen 
Modus an's laufen bringen, dann Dinge wie f = 1MHz testen. Am Ende Code 
der bei mir läuft, vielleicht hilft dir das.

@spess
Danke, wusste ich nicht. Ich habe bis jetzt nur gegenteiliges gehört.


void initADC() {
  // ADC Multiplexer Selection Register
  ADMUX = 0; // Reset ADMUX

  // 110 = internal 2.56V reference
  // 010 = internal 1.1V reference
  // X00 = Vcc as reference
  //ADMUX |= (1<<REFS2);
  ADMUX |= (1 << REFS1);
  //ADMUX |= (1<<REFS0);
  //ADMUX = (1<<ADLAR);             // left adjustment for adc results


  // ADC Control and Status Register A
  uint8_t ADCSRA_temp = 0;
  ADCSRA_temp |= (1 << ADEN); // Enables ADC
  ADCSRA_temp |= (1 << ADSC); // Start Conversion is enabled
  ADCSRA_temp |= (1 << ADATE); // auto trigger enable
  //ADCSRA_temp |= (1 << ADIF); // ADC interrupt flag
  ADCSRA_temp |= (1 << ADIE); // ADC Interrupt enable
  ADCSRA_temp |= (1 << ADPS2);
  ADCSRA_temp |= (1 << ADPS1); // Set ADC Prescaler to 64
  ADCSRA_temp |= (1 << ADPS0);
  ADCSRA = ADCSRA_temp;

  // ADC Control and Status Register B
  ADCSRB = 0;
  //ADCSRB |= (1<<BIN);      // defines bipolar mode. only useful for differential mode
  //ADCSRB |= (1<<IPR);        // input polarity reversal mode.
  //ADCSRB |= (1<<ADTS2);      // Auto trigger source. 000 = free running
  //ADCSRB |= (1<<ADTS1);
  //ADCSRB |= (1<<ADTS0);
} // end initADC()

// 1111 = temperature on attiny25
// Turns on Single Channel Measurement
inline void setADC(unsigned char channel) {
  ADMUX &= ~(1 << MUX3) & ~(1 << MUX2) & ~(1 << MUX1) & ~(1 << MUX0); // Set all ADC Channel bits to 0
  ADMUX |= (channel & 0x0f); // sets the bits again,
}

ISR(ADC_vect){

}

Autor: Sebastian O. (sebas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

na ja, meine Einstellungen sind gleich.

Ich werde nochmal alles prüfen.

Vielen Dank.

sebas

Autor: Sebastian O. (sebas)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe nochmal den Code für Free-Running Funktion angeschaut. Die 
Interrupt-Routine wird angerufen, aber das Bist ADSC wird nicht mehr 
gesetzt. Ich habe probiert, das Bit ADSC manuell zu setzen. In diesem 
Fall läuft der AD-Wander mit falscher Free-Running Funktion, weil 
manuell das Bit setzten muss. In diesem Fall würde ich Single Conversion 
Mode verwenden, da die gleiche Funktionalität hat.

Grüsse,

sebas

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Die Interrupt-Routine wird angerufen, aber das Bist ADSC wird nicht mehr
>gesetzt.

Warum auch? Wird nur für die erste Wandlung gebraucht.

>Ich habe probiert, das Bit ADSC manuell zu setzen. In diesem
>Fall läuft der AD-Wander mit falscher Free-Running Funktion, weil
>manuell das Bit setzten muss. In diesem Fall würde ich Single Conversion
>Mode verwenden, da die gleiche Funktionalität hat.

Ich habe es auch probiert. Das angehängte läuft wunderbar im Simulator2.

MfG Spess

Autor: Sebastian O. (sebas)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe die zwei Coden mit Simulator2 und die Interrupt-Routine des 
AD-Wandlers wird aufgerufen. Das bedeute, dass die Konvertierung gemacht 
wird. Trotzdem bleibt das Bit ADSC gelöst. Wie kann das möglich sein?

Grüsse,

sebas

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.