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?
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.
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?
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.
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
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.
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
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!
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!
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.