PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ADCH & ADCL nicht richtig übernommen



Bunch
25.11.2005, 07:59
Hallo alle miteineander,

Ich habe einen ATmega32 und programmiere mit AVR-Studio4.11.

Ich will die Spannung am PA4 messen und bei unterschreiten eines Schwellwertes eine Störungs-LED schalten.

Im Idealfall liegen 5V an PA4 an, und dies würde ja einen dezimalen Wert von 1024 machen. Wobei dann das Highbyte ( ADCH ) 3 sein muß und Lowbyte (ADCL) 255.

Wenn das Programm nun an den fett markierten Zeilen das ADCH und ADCL in Register übernehmen soll, wird das nicht richtig gemacht.

Es fehlen Bits im HighByte so als ob der Wert nach linksgeschoben worden wäre. D.h. wenn der Wert im ADCH ursprünglich 3 war ist er nachher nur noch 2, was sich doch ganz erheblich auf das Endergebniss auswirken kann.

Dies passiert jedoch nicht immer, wie ich bei debuggen feststellen konnte.

Hier mal der Teil-Code:


ldi temp,4;Spannungsmessung an PA4 !!!!!!!!!!!
out ADMUX, temp
ldi temp, ((1<<ADEN)|(1<<ADSC)|(1<<ADFR)) + 7 ;
out ADCSRA, temp

sbi ADCSRA, ADIF ;logisch "1" löscht ADIF flag !
;ADC einlesen:
in lowByte, ADCL ;immer zuerst low byte lesen
in highByte, ADCH ;danach high byte

ldi temp, high(900)
cpi lowByte,low (900)
cpc highByte,temp
brlo Storung

ldi temp,0b00010000
out PORTB,temp


Wieso wird der Wert nicht immer richtig übernommen?
Als Anmerkung sei gesagt, daß dies nur ein Ausschnitt aus dem Code ist.

Bin für alle Tips dankbar,

mit den besten Grüssen........

PicNick
25.11.2005, 08:22
ldi temp, ((1<<ADEN)|(1<<ADSC)|(1<<ADFR)) + 7 ;
da einfach die Zahl 7 zu verwenden ist "Pfui Gack" . Vielleicht ist da
"Adjust left" dabei ?

Bunch
25.11.2005, 12:51
Danke für den Tip,
aber jedoch ist ADLAR (adjust left result) im ADMUX Register untergebracht, und nicht aktiviert.

Das Problem ist ja das es nicht immer vorkommt, sondern nur sporadisch, aber dadurch wird bei nem falsch eingelesenen Ergebnis
die Verzweigung zum Problem.

die ADCH und ADCL Werte stimmen ja auch, nur werden eben diese Werte so nicht in die Arbeitsregister übernommen.

Ich könnt k.......

PicNick
25.11.2005, 13:07
*grübel*

...als ob der Wert nach linksgeschoben worden wäre. D.h. wenn der Wert im ADCH ursprünglich 3 war ist er nachher nur noch 2, was sich doch

Von 3 nach 2 ist doch keine Linksverschiebung ?


btw: maximalwert ist 1023 (0x03FF), nicht 1024

Bunch
25.11.2005, 13:44
OK, entschuldigung

Hab nach geschaut:

das ADCH war 3 und wird dann 1 !!!

Und natürlich hast du auch recht mit den 1023,

habe mich vertan, -sorry

jedoch kann ich mir nicht erklären wo das herkommt.

Das SREG Register hab ich mir auch mal genau angeschaut, aber nichts aussergewöhnliches feststellen können.

Bunch
25.11.2005, 13:50
Ach ja,

und das komische ist, wenn ich es im Einzelschritt mit F11 durchmache scheint es zu gehen, wenn ich davor und danch Brakpoints setzte und mit F5 anspringe scheint der Fehler da zu sein !!!

versteh ich nich..................

PicNick
25.11.2005, 13:57
Ok. Aber genaugenommen sagt das nur, daß nach mehreren Messungen mit 0x03nn eine mit 0x01nn dazwischenrutscht.

(Ich setze voraus, daß du vorher brav auf das Fertigwerden des ADC gewartet hast, in dem Beispiel oben sieht man das nämlich nicht)

Ansonst fällt mir,ehrlich gesagt, nichtmehr viel ein. Für dynamische Sachen halte ich nicht viel vom Simulator / Debugger.
Wo kommt bei simulieren eigentlich der ADC Wert her ?

Bunch
25.11.2005, 14:32
Ok. Aber genaugenommen sagt das nur, daß nach mehreren Messungen mit 0x03nn eine mit 0x01nn dazwischenrutscht.


Ich habe ein JTAG ICE mit dem ich debugge und das mir auch den ADC-Wert einliest. ich habe inefach mak zu m test einen Taster des STK500 an den ADC-Pin angelegt der mir 5V liefert. Somit ist obige Aussage ausgeschlossen-oder?




(Ich setze voraus, daß du vorher brav auf das Fertigwerden des ADC gewartet hast, in dem Beispiel oben sieht man das nämlich nicht)


Weiß ehrlich gesagt nicht was du damit meinst !??!


Ich lese ein, und gleich eine Zeile danch beginne ich mit dem Vergleich der Werte. Auf was soll ich da Warten? Und wie ????

Hier nochmal der Ausschnitt:


in lowByte, ADCL ;immer zuerst low byte lesen
in highByte, ADCH ;danach das high byte

ldi temp, high(900)
cpi lowByte,low (900)
cpc highByte,temp
brlo Storung

PicNick
25.11.2005, 14:52
Uiii. wenn so ist, das isses klar:

Du mußt nach dem Starten des ADC warten, (schleife), bis ADIF gesetzt ist, erst dann ist er fertig mit dem messen
und DANN erst den Wert lesen.

Im F11 mode wär's klar, das ist er locker fertig, bis du steppst,
aber im Break/ F5-Mode schafft er das nichtmehr.

seite 213 im datasheet !

Bunch
28.11.2005, 09:52
Ok,
hab ich irgendwie nicht beachtet.

Hab jetzt aber ne Schleife eingebaut:


loop:


ldi temp, 0 ;
out ADCSRA, temp
sbi ADCSRA, ADIF ;logisch "1" löscht ADIF flag !
ldi temp,4
out ADMUX, temp
ldi temp, ((1<<ADEN)|(1<<ADSC)|(1<<ADFR)) +7 ;
out ADCSRA, temp

Wart:
sbis ADCSRA, ADIF
rjmp Wart



in LB, ADCL ;immer zuerst low byte lesen
in HB, ADCH ;danach das gesperrte high byte


Und es scheint zu gehen.......

Besten Dank für die tolle Unterstützung !!!!!!!!!!
Viele Grüsse