Forum: Mikrocontroller und Digitale Elektronik mC mit schneller Ad-Wandlung


von Lars E (Gast)


Lesenswert?

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?

von Peter (Gast)


Lesenswert?

Lars E schrieb:
> Die Ursache könnte natürlich auch nicht an der AD-Wandlung liegen.

das denke ich auch, wird wohl an der Software liegen.

von Floh (Gast)


Lesenswert?

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).

von Falk B. (falk)


Lesenswert?

@  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.29

Multitasking

MfG
Falk

von Lars E (Gast)


Lesenswert?

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...

von Peter (Gast)


Lesenswert?

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?

von Weingut P. (weinbauer)


Lesenswert?

8-bit geht auch anders,den ADC konfigurieren für Daten linksbündig und
dann nur noch das highbyte auslesen ... bring mächtig Speed.

von Jens G. (jensig)


Lesenswert?

>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 ...

von Lars E (Gast)


Lesenswert?

ok, mal die entsprechenden Unterprogramme:
1
getOberw:    cbi     PORTB, 3
2
             ldi     EK, 0b00000010  ;ADC initialisieren  
3
             rcall   AD_Wandlung
4
             reti
1
AD_Wandlung: out     ADMUX, EK
2
             sbi     ADCSRA, ADSC    ; den ADC starten 
3
wait_adc:    sbic    ADCSRA, ADSC    ; warten auf AD-Wandlung
4
             rjmp    wait_adc
5
             reti

Konfiguriert habe ich es  ADCSRA 10011101


Ggf. verlängern massig Interupts die Messung.

von spess53 (Gast)


Lesenswert?

Hi

1. Unterprogramme beendet man nicht mit 'reti', sondern mit 'ret'
2. Warum setzt du ADIE, wenn du den ADC pollst?

MfG Spess

von Tom R. (rengi)


Lesenswert?

Wann wird denn der Port wieder gesetzt?
Mit welchem Tackt arbeitet der Mega8?

von Lars E (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

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".

von Tim (Gast)


Lesenswert?

> 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....

von Lars E (Gast)


Lesenswert?

OK, da ich befürchte, dass 700 Zeilen Code auch nichts nützen mal die 
weiteren relevanten Stellen:


Aufgeführt wegen der Interrupts
1
begin:    
2
rjmp  main      ; RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
3
reti            ;  INT0 External Interrupt Request 0
4
reti            ;  INT1 External Interrupt Request 1
5
reti            ;  TIMER2 COMP Timer/Counter2 Compare Match
6
reti            ;  TIMER2 OVF Timer/Counter2 Overflow
7
reti            ;  TIMER1 CAPT Timer/Counter1 Capture Event 
8
reti            ;  TIMER1 COMPA Timer/Counter1 Compare Match A
9
reti            ;  TIMER1 COMPB Timer/Counter1 Compare Match B
10
reti            ;  TIMER1 OVF Timer/Counter1 Overflow
11
rjmp    timer0_overflow  ;  TIMER0 OVF Timer/Counter0 Overflow
12
reti            ;  SPI, STC Serial Transfer Complete
13
reti            ;  USART, RXC USART, Rx Complete
14
reti            ;  USART, UDRE USART Data Register Empty
15
reti            ;  USART, TXC USART, Tx Complete
16
rjmp   on       ;  ADC ADC Conversion Complete
17
reti            ;  EE_RDY EEPROM Ready
18
reti            ;  ANA_COMP Analog Comparator
19
reti            ;  TWI 2-wire Serial Interface
20
reti            ;  SPM_RDY Store Program Memory Ready


Initialisieren des Timers und der UART
1
ldi     temp1, 0b00000001    ; TOIE0: Interrupt bei Timer Overflow
2
out     TIMSK, temp1
3
;------------------------------------------------------------------
4
sbi  UCSRB, 3
5
ldi  r16, 23
6
out  UBRRL, r16


Hier der Unterprogramm-Aufruf in der Schleife im Hauptgrogramm:
1
phase450:  
2
rcall  getOberw
3
cpi    Oberw, 110  ;gehe in Phase 500 wenn
4
BRSH   phase500    ;die Oberw erreicht ist
5
rjmp   phase450


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
1
on:      
2
sbrc  EK, 0    ;wenn Bit 1 von EK auf 1 steht,    
3
rjmp  onKw     ;dann springe zum verarbeiten des Kniewinkels
4
sbrc  EK, 1    ;wenn Bit 2 von EK auf 1 steht,    
5
rjmp  onOberw  ;dann springe zum verarbeiten des Oberschenkelwinkels
6
7
onMt: ;habe ich hier im Code mal beode weggelassen, da nicht relevant
8
onKw  ;es werden hier halt die anderen beiden Eingänge verarbeitet
9
10
onOberw:  
11
push  temp1        
12
push  temp2  ;rette  die Temps
13
    
14
in    temp1, ADCL    
15
in    temp2, ADCH
16
;-----------------------
17
asr   temp2  
18
mov   Oberw, temp1
19
ldi   temp1, 160
20
add   Oberw, temp1
21
    
22
putChar2:  
23
sbis  UCSRA, 5 ;gebe die Daten über den Comp aus
24
rjmp  putChar2
25
out   UDR, Oberw 
26
        
27
pop   temp2    ;schreibe die Temps zurück
28
pop   temp1
29
reti           ;und zurück ins Hauptprogramm


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.
1
timer0_overflow:       ; Timer 0 Overflow Handler
2
inc     PWMCount       ; den PWM Zähler von 0 bis
3
cpi     PWMCount, 101  ; 101 zählen lassen
4
brne    WorkPWM        ; springe wenn ungleich 101 zu WorkPWN
5
clr     PWMCount       ; wenn gleich lösche PWNCount
6
        
7
WorkPWM:      
8
push   temp1           ;rette Temp1
9
cbi    PORTB, 5        ;lösche PortB5
10
ldi    temp1, 100      ;lade 100 in temp1
11
sub    temp1, v        ;temp1=100 - v
12
        
13
cp     PWMCount, temp1 ;Vergleiche den Grenzwert (temp1=100-v) mit dem Zählwert PWMCount
14
brlo   zur1            ;wenn er niedrieger ist springe zu zur1
15
sbi    PORTB, 5        ;setzte PORTB5
16
 
17
zur1:   
18
pop    temp1           ;temp1 zurück schreiben
19
reti                   ;zrück zum Hauptgrogramm


Dann schon mal vielen Dank an alle die sich die Mühe machten bis hier zu 
lesen,

Grüße,

Lars

von Floh (Gast)


Lesenswert?

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.

von Tim (Gast)


Lesenswert?

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?

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
Noch kein Account? Hier anmelden.