Seit knapp einen Jahr arbeite ich als Werksstudent an einer Anwendung
mit einem Atmega8.
Laut Datenblatt soll hier die "Conversion-Time" der AD-Wandlung 13-250
microSec dauern.
Beobachtet habe ich eine Reaktionszeit, die eher bei einer 1/10 Sekunde
liegt.
Die Ursache könnte natürlich auch nicht an der AD-Wandlung liegen.
Ist der Atmega8 wirklich so langsam?
Gibt es eine schnelle alternative, die möglichst kompatibel ist?
Lars E schrieb:> Beobachtet habe ich eine Reaktionszeit, die eher bei einer 1/10 Sekunde> liegt.> Die Ursache könnte natürlich auch nicht an der AD-Wandlung liegen.
Wie hast du das beobachtet? mit den Augen?
Mann kann mit AVRs locker 200kSps erreichen, wenn man nicht allzu genaue
Werte braucht (also 8bit reichen).
@ Lars E (Gast)
>Laut Datenblatt soll hier die "Conversion-Time" der AD-Wandlung 13-250>microSec dauern.
Das ist auch so.
>Beobachtet habe ich eine Reaktionszeit, die eher bei einer 1/10 Sekunde>liegt.
Beobachtet? Wie?
>Die Ursache könnte natürlich auch nicht an der AD-Wandlung liegen.
das ist zu 100% der Fall.
>Ist der Atmega8 wirklich so langsam?
Nein.
>Gibt es eine schnelle alternative, die möglichst kompatibel ist?
Programmier richtig, dann klappts auch mit dem ADC.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29Multitasking
MfG
Falk
ich hatte vor der Messung einen Ausgang eingeschaltet und nach der
Messung wieder abgeschaltet und den Ausgang aufs Oszi gelegt...
Ich hatte allerdings eine 10 Bit Messung gemacht und die 2 lsb wegfallen
lassen.
gut- dann geht meine Ursachen-Forschung Richtung Software...
Lars E schrieb:> ch hatte vor der Messung einen Ausgang eingeschaltet und nach der> Messung wieder abgeschaltet und den Ausgang aufs Oszi gelegt.
gehört auch zufällig eine float/double berechnung zu der Messung?
>8-bit geht auch anders,den ADC konfigurieren für Daten linksbündig und>dann nur noch das highbyte auslesen ... bring mächtig Speed.
Begründet aber nicht, daß der µC 0,1s braucht ...
Dann versuche ich es so gut es geht zu beantworten ;)
> 1. Unterprogramme beendet man nicht mit 'reti', sondern mit 'ret'
habe ich ehrlich gesagt immer gemacht- funktioniert auch- hat das
irgendworauf einen Einfluß? Ich werde es ändern...
> 2. Warum setzt du ADIE, wenn du den ADC pollst?
genauso gute Frage- änder ich auch.
> Wann wird denn der Port wieder gesetzt?
Ich arbeite mit einer automatensteuerung- sprich ich befinde mich in
einer schleife- rufe getOberw auf, prüfe ob der wert den Sollwert
erreicht hat und wiederhole die Schleife bis er den Wert erreicht hat.
> Mit welchem Tackt arbeitet der Mega8?
er arbeitet mit 3.68864 Mhz
Danke schon mal für die ganzen Antworten,
Grüße,
Lars
Hi
>habe ich ehrlich gesagt immer gemacht- funktioniert auch- hat das>irgendworauf einen Einfluß?
Ja. Das wirkt zusätzlich wie 'sei'. Kann also ein vorheriges 'cli'
unwirksam machen.
MfG Spess
Lars E schrieb:> habe ich ehrlich gesagt immer gemacht- funktioniert auch- hat das> irgendworauf einen Einfluß? Ich werde es ändern...
Im Prinzip machen beide Befehle das gleiche, nur dass bei reti
zusätzlich Interrupts wieder freigegeben werden. Also ein atomares "sei
+ ret".
> Konfiguriert habe ich es ADCSRA 10011101> er arbeitet mit 3.68864 Mhz
Macht also 3688640/32/13 = 8866,9 Wandlungen / Sec
Ergo 112,7 µSec für eine.
Also bist du mit deinen 0,1 Sec ca Faktor 1000 daneben.
Poste mal mehr code....
Hier der Unterprogramm-Aufruf in der Schleife im Hauptgrogramm:
1
phase450:
2
rcallgetOberw
3
cpiOberw,110;geheinPhase500wenn
4
BRSHphase500;dieOberwerreichtist
5
rjmpphase450
Interrupt bei neuem AD-Wert, Verarbeitung und Ausgabe per UART
Verarbeitung ist natürlich notwendig- wenn die UART-Ausgabe sehr viel
Zeit benötigt könnte sie weggelassen werden, ist z.Z. vor allem zur
Kontrolle für mich
Timer, der ggf, auch ein paar mal reinhackt- nutze ich sowohl zur
"Zeitmessung" aber vor allem für ein PWM-Signal zur Motorsteuerung.
Ist leider an dieser Stelle auch nötig- aber es läßt sich bestimmt auch
anders realisieren.
vorher hast du die analogmessung noch gepollt, jetzt ist plötzlich ein
Interrupt da, in dem du auch noch sehr langwierige Dinge tust (serielle
Übertragung).
Poste mal deinen GESAMTEN Code als Anhang, diese Häppchentaktik bringt
uns und damit dir nichts.
Wenn ich das jetzt richtige zusammen gesammelt habe hast du folgenden
Ablauf Programmiert:
phase450:
rcall getOberw
ldi EK,.... für die Mux
AD_Wandlung:
adc start und warten bis fertig.
IRQ ADC fertig
Verarbeitung ja nach EK und Ausgabe via UART
Von wo bis wo hat du die 0,1 sek gemessen?
Und dann noch ein parr Fragen zum Code:
Wo und wie sicherst du das SREG in den ISR? Wiederherstellung?
Warum fragst du in on: nicht das ADMUX register ab?
EK ist was du messen wolltest, ADMUX das was du gemessen hast.
Was wolltest du hier rechnen:
1
in temp1, ADCL
2
in temp2, ADCH
3
;-----------------------
4
asr temp2
5
mov Oberw, temp1
6
ldi temp1, 160
7
add Oberw, temp1
Oberw = ADCL + 160? Überlauf? ADCH egal?
Also ist Oberw von 0..Vref 4x hintereinander 160..255..0..159
Warum verwendest du keine Hardware PWM mit Timer 1/2?