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
>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
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.
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.
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
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
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?
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
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
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
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
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
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:>
1
// 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>
1
In Single Conversion mode, write this bit to one to start each
2
> conversion. In Free Running mode, write this bit to one to start the
3
> first
4
> 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.
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.
1
voidinitADC(){
2
// ADC Multiplexer Selection Register
3
ADMUX=0;// Reset ADMUX
4
5
// 110 = internal 2.56V reference
6
// 010 = internal 1.1V reference
7
// X00 = Vcc as reference
8
//ADMUX |= (1<<REFS2);
9
ADMUX|=(1<<REFS1);
10
//ADMUX |= (1<<REFS0);
11
//ADMUX = (1<<ADLAR); // left adjustment for adc results
12
13
14
// ADC Control and Status Register A
15
uint8_tADCSRA_temp=0;
16
ADCSRA_temp|=(1<<ADEN);// Enables ADC
17
ADCSRA_temp|=(1<<ADSC);// Start Conversion is enabled
18
ADCSRA_temp|=(1<<ADATE);// auto trigger enable
19
//ADCSRA_temp |= (1 << ADIF); // ADC interrupt flag
20
ADCSRA_temp|=(1<<ADIE);// ADC Interrupt enable
21
ADCSRA_temp|=(1<<ADPS2);
22
ADCSRA_temp|=(1<<ADPS1);// Set ADC Prescaler to 64
23
ADCSRA_temp|=(1<<ADPS0);
24
ADCSRA=ADCSRA_temp;
25
26
// ADC Control and Status Register B
27
ADCSRB=0;
28
//ADCSRB |= (1<<BIN); // defines bipolar mode. only useful for differential mode
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
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
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