Forum: Mikrocontroller und Digitale Elektronik ADC Zeit Problem


von René (Gast)


Lesenswert?

Hallo,

ich benötige eine Schleife durch einen ADC Hindurch aTMEGA16
Die von der Zeit her immer konstant ist. Das Problem besteht darin das 
der ADC pro wert immer unterschiedlich viele Zyklen braucht. kann man 
die Zyklen irgendwie erfassen? Die schleife schon läuft in einem 
Interrupt.
Habt Ihr Ideeen wie man das lösen kann?

von 6637 (Gast)


Lesenswert?

Der ADC hat immer gleich lange. Man kann den ADC mit sich selbst 
starten, oder von einem Timer. Wenn das Timing sehr stabil sein muss, 
unbeeinflusst von irgendwelchen interrupts, so sollte man sich nach 
einem CPLD/FPGA umschauen.

von le maestro (Gast)


Lesenswert?

Der ADC wert braucht unterschiedliche Zyklen? Das waere wirklich 
merkwuerdig... oder braucht deine Schleife immer unterschiedlich lange, 
vielleicht wir sie von nem anderen Interrupt unterbrochen. Kenne den 
Controller jetzt nicht, aber kann man da keine Prioritaeten fuer 
Interrupts setzen?

von STK500-Besitzer (Gast)


Lesenswert?

Den ADC des Mega16 kann man, soweit ich mich recht erinnere, per Timer 
starten. Dann würde der Timmer immer im selben Intervall gestartet 
werden.

von René (Gast)


Lesenswert?

Hallo,

habe diese schleife im Interrupt mit ein bisschen gerassel vorneweg und 
hinterher die aber mit nop usw, angepasst sind ohne ADC sind die Zeiten 
konstant. Mache ich die ADC Schleife hinzu dann ändern sich die Zeiten.
Im AVR Studio sind die Zeiten gleich in der Praxis nicht.

start:
        sbi     ADCSRA, ADSC
wait:   sbic    ADCSRA, ADSC
rjmp    wait


Ich frage nacheinander 3 verschiedene Eingänge im Interrupt ab sobald 
ich die ADC Schleife einfüge "Wandern die Zeiten". Schleife ADC + 
darüber liegende Schleife für das Umschalten und Speichern der Werte im 
RAM. Schleifen wurden mit nop wegen der Sprünge angepasst und im 
Simulator sind die Intervalle immer
gleich. ob mit oder ohne ADC Schleife in der Praxis leider nicht.

bin echt ratlos

von Johannes M. (johnny-m)


Lesenswert?

Warum schickst Du nicht den kompletten Code? Und warum nutzt Du nicht 
den ADC-Interrupt? Eine Warteschleife mit derart großen Zeitkonstanten 
in einem Interrupt Handler ist miserabler Programmierstil! Auf die 
Weise wundert mich überhaupt nicht, dass Du Timing-Probleme bekommst.

Und auch wenn Du es nicht glauben willst: Bis auf die erste Wandlung 
nach dem Einschalten dauern alle Wandlungen prinzipbedingt gleich lange.

von René (Gast)


Lesenswert?

1
Kanalwahl:     
2
            cpi    Flag,0
3
            brne   nex01
4
      nop
5
      nop
6
      nop
7
      nop
8
      nop
9
      nop
10
      nop
11
      nop
12
      nop
13
            ldi    tempL,(0<<MUX1)|(0<<MUX0)|(1<<REFS1) |(1<<REFS0) |(1<<ADLAR) | (0<<MUX3) ;Kanal 0 (Rot)
14
            out    ADMUX,tempL
15
            rjmp   a
16
nex01:      cpi    Flag,1
17
            brne   nex02
18
      nop
19
      nop
20
      nop
21
      
22
            ldi    tempL,(0<<MUX1)|(1<<MUX0)|(1<<REFS1) |(1<<REFS0) |(1<<ADLAR) | (0<<MUX3) ;Kanal 1(Grün)
23
            out    ADMUX,tempL
24
      
25
                                               
26
            rjmp   a
27
nex02:      cpi    Flag,2
28
            brne   a
29
            ldi    tempL,(1<<MUX1)|(0<<MUX0)|(1<<REFS1) |(1<<REFS0) |(1<<ADLAR) | (0<<MUX3) ;Kanal 2(Blau)
30
            out    ADMUX,tempL
31
            nop
32
a:           
33
             clr     zaehl
34
       clr     puf1
35
36
           
37
weiter:
38
Toggel:    sbis    portC,0 ;toggeln portC,0 für Anzeige auf Monitor
39
           rjmp    PC0an
40
           rjmp    PC0aus
41
PC0an:     sbi     PortC,0
42
           rjmp     Toggel1
43
PC0aus:    cbi     PortC,0
44
            nop      
45
      
46
Toggel1:    sbis    portC,0 ;toggeln portC,0 für Anzeige auf Monitor
47
           rjmp    PC0an1
48
           rjmp    PC0aus1
49
PC0an1:     sbi     PortC,0
50
           rjmp     start_adc
51
PC0aus1:    cbi     PortC,0
52
            nop
53
      
54
      
55
      
56
    
57
       
58
59
                     
60
;********************Messung*****************************************************           
61
start_adc:  
62
            sbi     ADCSRA, ADSC        ; den ADC starten
63
wait_adc:   sbic    ADCSRA, ADSC
64
           
65
            rjmp    wait_adc
66
67
      
68
            
69
70
71
;************************************************************************
72
73
74
mittel:     in      PUF0 ,ADCL
75
           in      temph ,ADCH ;
76
77
                              
78
           
79
          ;lsr     tempH
80
          ;lsr     tempH
81
          ;lsr     temph
82
      
83
                    ;/8
84
      add     puf1,tempH
85
      inc     zaehl
86
      cpi     zaehl,1
87
      brne    weiter
88
         
89
          clr     zaehl
90
          
91
92
93
                                  
94
weit0:      cpi    flag,0
95
          brne   weit1
96
          sts    Rot,Puf1
97
          inc    Flag
98
             ;Flag +1
99
          rjmp   Kanalwahl
100
weit1:      cpi    flag,1
101
        brne   weit2
102
        sts    Gruen,Puf1
103
        inc    Flag  
104
            ;Flag +1
105
            rjmp   Kanalwahl
106
weit2:      
107
            sts    Blau,Puf1
108
            clr    Flag          ;Lösche Flag um wieder bei Null zu

hier der Relevate Teil durch die Teilweise Rumprobierrei ist es ziemlich 
Caotisch. Serg und andere Register werden vorher gesichert und nachher 
wieder zurückgeschrieben hab das jetzt weggelassen

von Johannes M. (johnny-m)


Lesenswert?

René wrote:
> hier der Relevate Teil durch die Teilweise Rumprobierrei ist es ziemlich
> Caotisch. Serg und andere Register werden vorher gesichert und nachher
> wieder zurückgeschrieben hab das jetzt weggelassen
Ich habe gesagt KOMPLETTER Code! Schreibe ich so undeutlich?

Und wenn das da oben alles in einer Interrupt Routine steht, dann 
brauchst Du Dich über gar nichts zu wundern!

von René (Gast)


Lesenswert?

Seit wann darf in einem IR nur 3 Zeilen Code stehen?

von Johannes M. (johnny-m)


Lesenswert?

René wrote:
> Seit wann darf in einem IR nur 3 Zeilen Code stehen?
Habe ich nicht behauptet. Ich habe lediglich darauf hingewiesen, dass 
Warteschleifen in Interrupt Handlern meist dazu führen, dass es 
Timing-Probleme gibt. Und Du hast noch nicht mal erzählt, welchen 
Interrupt Du da überhaupt verwendest. Aber wenn Du nicht mit dem Code 
rausrückst, dann wünsche ich Dir noch einen schönen Tag. Das kann doch 
nicht so schwer sein!

von Michael U. (amiga)


Lesenswert?

Hallo,

ich mache solche Sachen eigentlich immer im Timer-IRQ.

Die Zeit des Timer-IRQ so lang, daß es für eine ADC-Wandlung + ein paar 
Takte Reserve reicht.

Dann muß ich die Fertig-Meldung des ADC garnicht auslesen, er ist immer 
fertig.
Wert holen, neu starten, Flag für Daten da setzen, raus.
Bei mehreren zu wandelnden Eingängen eben entsprechend viele Flags 
vereinbaren und dann im Kreis rum. Webb Dummy-Zyklen nötig sind 
(Umschalten von ARef oder sonstige Gründe, dann eben Hilfsflag und 
ersten Wert wegwerfen.

Wenn nur die Eingänge wechseln, kann man die Timer-Zeit auch auf die 
Hälfte setzen und im IRQ "dazwischen" den MUX schon umschalten.

Die Timerzeit hängt dann davon ab, wie oft ich überhaupt neue Werte 
einlesen will.

Wenn man sich das Zeitraster einaml aufgestellt hat, bleibt da nur wenig 
Code übrig.

Gruß aus Berlin
Michael

von René (Gast)


Lesenswert?

Hallo,

Gute Idee das mit dem Timer IRQ aber den würde das auch mit einer 
normalen schleife als Pause funktionieren. Ich Zähle also im AVR Studio 
die Zyklen gebe noch ein bisschen reserve dazu und lese dann den ADC aus 
und habe immer die selbe Pause zwischendurch.

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.