Hallo, ich habe an den ADC-Eingang eines AtMega8 (AVR-P28 von Olimex) mit einen Spannungsteiler einen Transitor als Temperatursensor angeschlossen (siehe http://de.wikipedia.org/w/index.php?title=Datei:NPN_Thermometer_Schaltung.svg&filetimestamp=20090330185439) das auslesen funktioniert ganz gut, man sieht auch wie sich der Messwert ändert, wenn man den Transistor erwärmt. Allerdings liefert der ADC immer abwechslend einen plausiblen Messwert (hier 42) und einmal 0. Dazwischen springt er immer hin und her. Lese den ADC per Interrupt 5 mal pro Sekunde aus, Mittelung mache ich keine. Liegt das an schlechter Verdrahtung am ADC-Pin (kann gut sein) oder hab ich irgendwo den ADC falsch eingestellt? Orientiert habe ich mich am Assembler-Tutorial Viele Grüße, Ludwig
Gast
#2492976
Ludwig P. schrieb: > oder hab > ich irgendwo den ADC falsch eingestellt? Glaskugel sagt: Nein. Quellcode!!!!
Gast
#2492982
Hi ADC-Takt im grünen Bereich? MfG Spess
Quellcode hab ich grad nicht da, kommt sobald ich zuhause bin^^ ADC-Takt liegt bei 62,5kHz (8MHz Takt und 128-Prescaler)
So, hier ist der Quelltext
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
Probehalbe Multiplier auf 64 setzen hat auch nicht geholfen. Nochmal Danke! Ludwig
Gast
#2493365
Du liest nie ADCL aus, machst du das bewusst? Teste vielleicht mal:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Gast
#2493370
Achtung zuerst ADCL dann ADCH lesen! Beim Auslesen der ADC-Register ist zu beachten: Immer zuerst ADCL und erst dann ADCH auslesen. Beim Zugriff auf ADCL wird das ADCH Register gegenüber Veränderungen vom ADC gesperrt. Erst beim nächsten Auslesen des ADCH-Registers wird diese Sperre wieder aufgehoben. Dadurch ist sichergestellt, daß die Inhalte von ADCL und ADCH immer aus demselben Wandlungsergebnis stammen, selbst wenn der ADC im Hintergrund selbsttätig weiterwandelt. Das ADCH Register muss ausgelesen werden! http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC#Die_Ergebnisregister_ADCL_und_ADCH
1 | |
2 | |
Gast
#2493373
Hi
>Du liest nie ADCL aus, machst du das bewusst?
Es ist ADLAR gesetzt. Da braucht man das nicht.
MfG Spess
Gast
#2493379
.....ist aref konstant genug? 2,2mV/°C sollte man gut messen können,allerdings nur so exakt wie aref....
Gast
#2493392
Du vertauschst in timer0_overflow und delay5ms die gesicherten Register. Wenn man mehrere Werte auf den Stack legt,
1 | |
2 | |
muß man sie in der umgekehren Reihenfolge wieder runterholen.
1 | |
2 | |
Wenn ich ADCL zuerst auslese, und dann gleich verwerfe, ändert das leider gar nichts. Sollte meiner Meinung auch keinen Unterschied machen, da ich die Wandlung ja mit
1 | |
anstoße, dann mit
1 | |
2 | |
3 | |
warte, bis das Ergebnis da ist (also bis ADSC wieder gecleared ist) und dann erst das Ergebnis mit
1 | |
auslese. Zur Erklärung: Ich möchte nur 8 Bit ausgeben. Deshalb ist auch ADLAR gesetzt, und ADCL wird nicht ausgwertet, und wurde deshalb auch nicht ausgelesen
GeraldB schrieb: > Du vertauschst in timer0_overflow und delay5ms die gesicherten > Register. > > Wenn man mehrere Werte auf den Stack legt, >
1 | |
2 | |
3 | |
> muß man sie in der umgekehren Reihenfolge wieder runterholen. >
1 | |
2 | |
3 | |
Danke, habe ich auch korrigiert! Leider wieder ohne das Problem zu lösen
Wenn ich das ADC-Pin offen lasse, krieg ich übrigends immer 255 und 0 als Wandelergebniss...das versteh ich nun wirklich nicht :-(
Gast
#2493415
Hi
>Danke, habe ich auch korrigiert! Leider wieder ohne das Problem zu lösen
Hat auch keinen Einfluss, da die Register nicht im 'loop' verwendet
werden.
Vielleicht solltest du doch mal deine Hardware überprüfen. Was sagt das
Multimeter am ADC-Pin?
MfG Spess
Mh, das hüpft recht munter zwischen 4,2V und 4,9V umher. Was mich aber sehr wundert, ist das wenn ich den Pin offenlasse, der Wert auch hin und her springt
Gast
#2493457
Noch so ein Freak der unbedingt Assembler schreibt wo es nur wirklich nicht sein muss. Fällt doch schon fast unter Sado/Maso. Naja es gibt auch Leute die von Hamburg nach München zu Fuß gehen, nur weil es geht statt zu fahren......
Problem gefunden! Wenn ich die LED nicht blinken lasse, springt auch der ADC-Wert nicht. Bitte um ein Herz für Anfänger :-P
Gast
#2493464
Ludwig P. schrieb: > Problem gefunden! Wenn ich die LED nicht blinken lasse, springt auch der > ADC-Wert nicht. Nicht das Problem, nur ein Symptom...... Die Ursache kennst du noch nicht. ==> weitersuchen
Gast
#2493465
....und,warum ist das so? ;-)
Gast
#2493468
Es gibt ein Race Condition zwischen dem timer und dem ADC + LCD init. Wenn der timer reinkommt bevor die initialisierung abgeschlossen ist, kracht es. Ein Fix könnte sein das "sei" direkt vor die (leere) mainloop zu verschieben.
Ich denke, das auf den Olimex Board die Referenzspannung nicht ausreichend stabilisiert ist (z.B. fehlt die Induktivität völlig). Und da ich immer genau dann den ADC auslese, wenn ich die LED schalte nehme ich an, dass das auch die Referenzspannung in Mitleidenschaft zieht. Auf jeden Fall funktionierts jetzt einwandfrei
smoerre schrieb: > Es gibt ein Race Condition zwischen dem timer und dem ADC + LCD init. > Wenn der timer reinkommt bevor die initialisierung abgeschlossen ist, > kracht es. > Ein Fix könnte sein das "sei" direkt vor die (leere) mainloop zu > verschieben. Woran man doch alles nicht denkt, ihr seit echt gut :-D
Ludwig P. schrieb: ... > Und > da ich immer genau dann den ADC auslese, wenn ich die LED schalte nehme > ich an, dass das auch die Referenzspannung in Mitleidenschaft zieht. Auf > jeden Fall funktionierts jetzt einwandfrei > Das sich das so stark auswirkt, hätte ich nicht gedacht. Siehe Seite 196 Punkt 4 im Datenblatt. Analog Noise Canceling Techniques ... 4. If any ADC [3..0] port pins are used as digital outputs, it is essential that these do not switch while a conversion is in progress. However, using the Two-wire Interface (ADC4 and ADC5) will only affect the conversion on ADC4 and ADC5 and not the other ADC channels Bernd_Stein
Ludwig P. schrieb: > out PORTC, led ;LED blinken lassen > com led Damit invertierst Du alle Bits des PortC, was zur Folge hat, dass Du den PullUp-Widerstand des ADC-Eingangs ein/ausschaltest. Dieser sorgt dann für falsche Werte. Bernd Stein schrieb: > Das sich das so stark auswirkt, hätte ich nicht gedacht. Ich auch nicht. Aber das wirkt sich ja nicht so aus, die Ursache ist ja der toggelnde interne PullUp. ...
Hannes Lux schrieb: > Ludwig P. schrieb: >> out PORTC, led ;LED blinken lassen >> com led > > Damit invertierst Du alle Bits des PortC, was zur Folge hat, dass Du den > PullUp-Widerstand des ADC-Eingangs ein/ausschaltest. Dieser sorgt dann > für falsche Werte. > ... > Vielleicht habe ich es ja übersehen, irre mich oder versteh wieder mal etwas nicht richtig. Aber um überhaupt einen ADC-Kanal nutzen zu können muß dieser doch als Eingang geschaltet sein bzw. um den Pull-Up einschalten zu können muß ich doch den Portpin als Eingang schalten ( DDRCx = 0 ) und dann den Portpin setzten ( PortCx = 1 ). Wo geschieht dies im Programm ? Habe nur gefunden, das der komplette PortC als Ausgang geschaltet wird. main: ... ldi temp1, 0xFF out DDRC, temp1 ; Port C = Ausgang Bernd_Stein
Bernd Stein schrieb: > Wo geschieht dies im Programm ? out PORTC, led ;LED blinken lassen com led ;invertiert das ganze Byte und damit beim nächsten mal ;den ganzen Port, also auch den ADC-Eingang... > > Habe nur gefunden, das der komplette PortC als Ausgang geschaltet wird. Das habe ich nun wieder übersehen, da ich nicht weiter gesucht hatte, nachdem ich Obiges gesehen hatte. Aber das ist ja noch schlimmer, damit hat der Sensor ja gar keine Chance, seine Analogspannung messen zu lassen. Das Programm tut also genau das, was sein Autor programmiert hat, auch wenn der Autor eigentlich was ganz Anderes programmieren wollte. Das Verwenden der Aliasnamen Temp1 bis Temp4 suggeriert mir, dass hier unverstanden Teile des Tutorials kopiert wurden und diese dann mit "Anfänger-Naivität" mit eigenem Code ergänzt wurden. Das ist ansich nichts Falsches. Trotzdem wäre es sinnvoll, sich erstmal zum Thema "Bits & Bytes" Gedanken zu machen. Ein Anlaufpunkt könnte Bitmanipulation sein. ...
Gast
#2494080
Hi >Das habe ich nun wieder übersehen, da ich nicht weiter gesucht hatte, >nachdem ich Obiges gesehen hatte. Nein, du hast schon Recht. Bei eingeschalteten ADC wird der ausgewählte Kanal zum Eingang. Und dann greift der Pull-Up. MfG Spess
spess53 schrieb: > Hi ... > > Nein, du hast schon Recht. Bei eingeschalteten ADC wird der ausgewählte > Kanal zum Eingang. Und dann greift der Pull-Up. > Ich habe vor kurzem aus dem Datenblatt des ADC des ATtiny26 eine " Übersetzung " gemacht. Entweder habe ich dies überlesen, nicht richtig verstanden, es steht dort nicht oder ich habe es schlicht weg wieder vergessen. Könntest Du hier schreiben, auf welcher Seite dies beim ATmega8 im Datenblatt steht ? Nach dieser " Übersetzung " habe ich erstmal keine Lust alles im DB des ATmega8 noch selber abzusuchen. Wäre nett von Dir. Bernd_Stein
Gast
#2494117
Hi Diese Abhängigkeiten findet man unter I/O-Ports->Alternate Port Funktions. MfG Spess
Gast
#2494202
Hi >Nein, du hast schon Recht. Bei eingeschalteten ADC wird der ausgewählte >Kanal zum Eingang. Und dann greift der Pull-Up. Also ich habe mir das noch mal genau angesehen und kurz getestet. Und ich hatte Unrecht. Es wird nur der Analogeingang zugeschaltet. Portausgang und Pull-Up bleiben je nach DDRx erhalten und verfälschen das Ergebnis. Passt auch zu seinen Ergebnissen. Bei der Schaltung aus dem Ausganspost sollte die gemessene Spannung irgendwo zwischen 0,6 und 0,7V liegen und nicht bei 4,xxV. MfG Spess
spess53 schrieb: > Hi > > Diese Abhängigkeiten findet man unter I/O-Ports->Alternate Port > Funktions. > > MfG Spess > Danke, dort ist im Bild 25. Alternate Port Functions deutlich zu sehen das das AIOxn-Signal direkt von den Eingangspin abgenommen wird und die andere Seite wahrscheinlich direkt auf den Input MUX des ADCs geht ( Bild 90 ). Somit erklärt sich ja auch sein Problem, da er ja den kompletten PortC als Ausgang konfiguriert hat und diesen auch noch regelmäßig invertiert, liest er natürlich das PINC0 immer mit ein, und dies ist ja mal High und mal Low. Bernd_Stein
Gast
#2494407
Hi >dort ist im Bild 25. Alternate Port Functions deutlich zu sehen das das >AIOxn-Signal direkt von den Eingangspin abgenommen wird und die andere >Seite wahrscheinlich direkt auf den Input MUX des ADCs geht ( Bild 90 ). War mir schon klar. Ich war allerdings der (falschen) Meinung, das noch andere Steuerungen des Ports überschrieben werden, wie es z.B. UART,TWI ... machen. MfG Spess
Danke für die vielen Antworten. ja ich habe Teile des Sourcecodes einfach aus dem Tutorial übernommen, und obwohl ich dachte, dass ich ihn schon verstanden habe, habe ich ihn dennoch nicht selbst geschrieben, und das rächt sich jetzt. Man muss halt schon schaun, wie verschiedene Programmteile sich gegenseitig beinflussen, vorallem in Assembler
Ludwig P. schrieb: > Man muss > halt schon schaun, wie verschiedene Programmteile sich gegenseitig > beinflussen, vorallem in Assembler Dazu kommt noch, dass jeder ASM-Programmierer einen etwas anderen Stil hat. Kopiert man nun die Routinen von verschiedenen Quellen oder Autoren zusammen, dann wird es richtig haarig, dann gibt es Stilbruch... Daher ist es meist besser, nur die Algorithmen zu verstehen und zu übernehmen und seinen eigenen Code im eigenen Stil zu schreiben. Zumindest bin ich damit bisher immer ganz gut zurechtgekommen. Die Lernkurve ist zwar flacher, das erworbene Wissen aber solider. Bit- & Bytebruch, Hannes...
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.