Hallo !!! Folgendes Problem: Mir ist nicht klar warum ich nach einer Muxumschaltung ,14 Takte mehr brauche bis der gewandelte Wert korrekt ist. Das mir unbegreifliche ist , dass ich sogar auf das ADIF warte und danach noch 14 nop's einbauen muß !!!! Das Programm läuft auf einen ATMEGA8 bei 16Mhz, nicht im free-runnig-mode. Die Routine wirtd von einem exterenen Interrupt ausgelöst und soll schnellstmöglich 2 Kanäle abtasten.Der erste würde die 14 zusätzlichen nop's nicht brauchen. Der Mux wird genau einen Takt nach dem Start des ADC umgeschaltet. Bitte um Klärung des Problems, es kann doch nicht sein das ich nach conversion complete noch 14 Takte warten muß oder habe ich einen Fehler gemacht ??? Hier die Interruptroutine: ADC_HANDLER: sbrc Flags, GRAD_M ; Winkelmessung Aktiv ? rcall GRAD_MESSUNG sbrs Flags, ADC_RUN ; ADC Aktiv ? reti ; Nein -> Routine Abbrechen in REGSAVE, SREG ; Einlesen des SREG ldi i, 225 ; MUX auf Kanal 2 ADW: sbi ADCSRA, ADSC ; Start ADC nop ; zwingend für Mux-Umschaltung out ADMUX, i ; MUX auf Kanal 2 oder 1 sbis ADCSRA, ADIF ; Warte bis AD Wandlung fertig ist rjmp PC-1 nop nop nop nop nop nop nop nop nop nop nop nop nop nop in tempi, ADCH ; ADC einlesen ST X+,tempi ; DATEN SPEICHERN und Zeiger um 1 erhöhen ldi i, 224 ; für Kanal 1 (vorwahl) sbic ADMUX, MUX0 ; Kanal 2 schon gewandelt > fertig rjmp ADW ; Kanal 2 wandeln ldi tempi, high(adr_DATEN_SPEICHER+ANZAHL_DATENPUNKTE) cpi XL, low(adr_DATEN_SPEICHER+ANZAHL_DATENPUNKTE) cpc XH, tempi brlo ADC_HANDLER_ENDE ; Ende vom Speicher ? -> Aufzeichnung beenden clr Flags cbi PORTD,5 ADC_HANDLER_ENDE: out SREG, REGSAVE ; Wiederherstellen von SREG reti
War zu schnell: Wollte mich schon mal für die kommende Hilfe bedanken. LG Dieter
Hi >Mir ist nicht klar warum ich nach einer Muxumschaltung ,14 Takte mehr >brauche bis der gewandelte Wert korrekt ist. >Das mir unbegreifliche ist , dass ich sogar auf das ADIF warte und >danach noch 14 nop's einbauen muß !!!! Nur zur Vorabklärung: Wie kommst du darauf? MfG Spess
Aus dem Manual zum ATmega8, Seite 200: The user is thus advised not to write new channel or reference selection values to ADMUX until one ADC clock cycle after ADSC is written. Also dürfte sich Dein Problem in Luft auflösen, wenn Du erst den Kanal einstellst und danach die Wandlung startest.
spess53 schrieb:
> Nur zur Vorabklärung: Wie kommst du darauf?
Indem ich einmal Masse und einmal 5V anlege und am Kanal 1 bekomme ich
dann
den Wert 0 bzw. 255 (ohne die nop's),was richtig ist.Jedoch am 2. Kanal
bekomme ich Werte die größer 0 bzw. kleiner 255 sind, erst wenn ich die
14 nop's drinnen habe passt es.
LG Dieter
Nachteule schrieb: > Aus dem Manual zum ATmega8, Seite 200: > The user is thus advised not to write new channel or reference selection > values to ADMUX until one ADC clock cycle after ADSC is written. > > Also dürfte sich Dein Problem in Luft auflösen, wenn Du erst den Kanal > einstellst und danach die Wandlung startest. Wenn Du meinen Code anschaust wirst Du feststellen,das ich das mache: sbi ADCSRA, ADSC ; Start ADC nop ; zwingend für Mux-Umschaltung out ADMUX, i ; MUX auf Kanal 2 oder 1 LG Dieter
>> Also dürfte sich Dein Problem in Luft auflösen, wenn Du erst den Kanal >> einstellst und danach die Wandlung startest. > > Wenn Du meinen Code anschaust wirst Du feststellen,das ich das mache: 1. Wandlung starten: > sbi ADCSRA, ADSC ; Start ADC 2. Kanal umschalten: > nop ; zwingend für Mux-Umschaltung > out ADMUX, i ; MUX auf Kanal 2 oder 1 Also ich habe meine Probleme, zu sehen, wie du da erst den Kanal einstellst und danach die Wandlung startest.
>> "...one ADC clock cycle after..."
ADC clock ist nicht unbedingt gleich CPU clock! (ist abhängig von der
Prescaler Einstellung)
Rolf Magnus schrieb: > Also ich habe meine Probleme, zu sehen, wie du da erst den Kanal > einstellst und danach die Wandlung startest. Der 1. Kanal wird schon nach dem Reset eingestellt und schon mal eine Wandlung durchgeführt, da die erste Wandlung laut Datenblatt länger dauert.....der prescaler ist auf 0. Nach Aufruf der Routine wird der voreingestellte Kanal 1 gestartet und danach auf Kanal 2 umgestellt.Ohne den nop funktioniert es nicht und mit 2 nop's auch nicht, das habe ich getestet.Also die Umschaltung funktioniert ... nur eben wie gesagt brauche ich dann noch die 14 nop's bis der Wert stimmt. Danke erstmals LG Dieter
Wenn Referenzspannungsquellen umgeschaltet werden, sollte man noch dazu den ADC ausschalten und wiedereinschalten, um eine lange Wandlung (25 ADC-Clocks) durchzuführen, nur so kann das Ergebnis korrekt sein. Ansonsten gilt _immer_: 1. Wenn ADSC=0 oder ADIF=1, Ergebnisregister auslesen 2. ADMUX umschalten 3. Neue Wandlung auslösen
didi schrieb:
> der prescaler ist auf 0.
Kannste vergessen. Der ADC darf nur innerhalb 50...250kHz Samplerate
laufen, wenn Du 10Bit Auflösung haben willst. Bei 8Bit kannst Du bis
maximal 1MHz gehen. Stelle den ADC-Prescaler also auf 64.
Travel Rec. schrieb: > Kannste vergessen. Der ADC darf nur innerhalb 50...250kHz Samplerate > laufen, wenn Du 10Bit Auflösung haben willst. Bei 8Bit kannst Du bis > maximal 1MHz gehen. Stelle den ADC-Prescaler also auf 64. Ok ,ich brauche nur 8-Bit,müßte somit mit Teiler 16 gehen oder ? Werde ich mal testen,kann es aber erst am Dienstag probieren. Aber eines ist mir immer noch nicht klar, wieso klappt es beim Kanal 1 und komisch finde ich das ich ,das ich ADIF abwarte und danach noch 14 Takte warten muß bis das Ergebnis stimmt.Wieso kommt dann ADIF schon nach 13-Takte ? Danke nochmals LG Dieter
Hi >komisch finde ich das ich ,das ich ADIF abwarte und danach noch 14 Takte >warten muß bis das Ergebnis stimmt.Wieso kommt dann ADIF schon nach >13-Takte ? Dazu müsste man zumindest die Initialisierung des ADC und den Takt des Controllers kennen. MfG Spess
Hier: ldi temp, (1<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0) out ADMUX, temp ldi temp, (1<<ADEN)|(1<<ADIE) ;Teiler: 0 out ADCSRA, temp LG Dieter
Hi Du aktivierst den ADC-Complete-Interrupt. Gibt es da auch eine entsprechende Interrupt-Routine? MfG Spess
Nein,die habe ich nicht ,im Simulator springt er die zwar an aber dort habe ich reti und somit gehts wieder zurück. Ich wollte es aber eigentlich mit ADSC realisieren ,dieser ist solange gesetzt bis die AD-Wandlung fertig ist,hat aber auch nicht funktioniert bzw. komme ich auf das selbe Ergebnis als wenn ich es mit ADIF mache. LG Dieter
Hi Du bist dir aber bewusst, das du ADIF wieder manuell zurücksetzen must. Daher brauchst du auch die vielen 'nop's 'ADIF is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, ADIF is cleared by writing a logical one to the flag.' Deine ADIF-Abfrage ist sinnlos, weil dein Flag schon von der vorherigen Wandlung noch gesetzt ist. MfG Spess
Hi !! Könnte auch sein ,im Simulator wird es jedenfalls zurückgesetzt , aber wie gesagt das mag nichts heißen,der Sim. ist sicherlich nicht fehlerfrei. Danke jedenfalls das Du mich darauf aufmerksam gemacht hast, werde ich testen. LG Dieter
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.