Forum: Mikrocontroller und Digitale Elektronik ATmega32 Prob's mit ADC


von Kai S. (Firma: ZeuSWarE GmbH) (zeusosc)


Angehängte Dateien:

Lesenswert?

jo huhu,...
ich habe eine schaltung gebastelt an welcher ich so manche stellen die 
spannung auslesen will,.. zuerst dachte ich die schaltung sei falsch,..
aber dann habe ich ein 5V spannungsquelle mal an den ADC -PC0 und -PC2 
angeschlossen, und bemerkt das der muC mir bloß misst , also falsche 
werte übern rs232 schickt, im anhang alle dateien des prog's,..
ich weiß net ob ich da vlt was falsch eingestellt habe:
hier sie wesentlichen bestandteile:
>############################################################

>;Messbereich 0-5V, Kanal gnd (PC0) - 2neg (PC2) differnential
ldi temp, 0b01011000
out ADMUX, temp
>;ADC an, CLK=8MHz/128
ldi temp, 0b10000111
out ADCSRA, temp

>;start text
ldi send, STX
rcall sendbyte

ADC_START:
clr temp
>;Wandlung starten
sbi ADCSR,ADSC

warte_bis_feddich_gemessen:
>;Warten bis Wandlung beendet ist
sbis ADCSR,ADIF
rjmp warte_bis_feddich_gemessen

>;Die unteren 8 Bit in r17 merken
in zl, ADCL
>;Die oberen 2 Bit in r18 merken
in zh, ADCH

mov temp,zl
mov temp,zl
rcall hex2bcd

ldi send, ETX
rcall sendbyte
>####################################################################### ##



hmmm ich weiß leider net woran das liegt,...

von Stefan K. (_sk_)


Lesenswert?

>>;Die unteren 8 Bit in r17 merken
>in zl, ADCL
>>;Die oberen 2 Bit in r18 merken
>in zh, ADCH
>
>mov temp,zl
>mov temp,zl
>rcall hex2bcd

Das High-Byte (zh) wird nicht nach bcd gewandelt.

Gruß, Stefan

von Stefan K. (_sk_)


Lesenswert?

>int_RXD:
>    in temp,SREG
>    push temp

SREG wird im IR in temp gespeichert. Das überschreibt den Wert, den Dein 
Hauptprogramm in temp abgelegt hat!

Dein Interrupt int_RXD ist aktiv, bis alle Daten per send_byte über den 
UART versendet worden sind. Normalerweise soll ein IR nur sehr kurz 
aktiv sein.

Dein Programmierstil ist - vorsichtig ausgedrückt - etwas 
fehleranfällig. Solche Konstrukte:
>    brne PC + 5
>    pop temp
>    out SREG,temp
>    cli
>    rjmp wait
mögen zwar funktionieren, aber sobald Du etwas am Code änderst, springst 
Du an die falsche Stelle.

Überlege Dir mal, ob Du nicht besser auf C umsteigst. Viele Fehler 
werden Dir mit C nicht passieren (u.a. Überschreiben globaler Variablen, 
Übergabe in den falschen Registern, Stackfehler). Ich weiss wovon ich 
rede, ich habe selbst lange genug in ASM programmiert.

Gruß, Stefan

von johnny.m (Gast)


Lesenswert?

Öhh, hast Du Dein Messignal tatsächlich an PC0 und PC2 angeschlossen? 
Die Analog-Eingänge liegen beim Mega32 an Port A und nicht an Port C!

von Kai S. (Firma: ZeuSWarE GmbH) (zeusosc)


Lesenswert?

Ähm,.. ich meinte PADC0 und PADC2 :D

wegen dem zh, es sollte auch für kleine spannungen gehen also auch nur 
mit zl (8bit halt)

k, das mit dem temp
und die interrupt routine werde ich überarbeiten, hoffentlich funzt das 
dann ,
danke erstmal :)

von Kai S. (Firma: ZeuSWarE GmbH) (zeusosc)


Lesenswert?

jo hoi,.. am sreg dürfte das net liege, denn :

>#######################################################
int_RXD:
  in temp,SREG
  push temp
  in get,UDR
  cpi get,0
  brne PC + 2
        rjmp end_int_rxd


        cpi get,SI ;(ende der aufzeichnung)
  brne PC + 5
  pop temp
  out SREG,temp
  cli
  rjmp wait

  cpi get,255 ;(Grundstellung)
  brne PC + 4
  pop temp
  out SREG,temp
  rjmp reset ;hier auch statusregister sichern??

  lc_modus 1,0b00000001
  lc_modus 2,0b00000010
  lc_modus 3,0b00000100
  lc_modus 4,0b00001000
  lc_modus 5,0b00010000
  lc_modus 6,0b00100000
  lc_modus 7,0b01000000
  lc_modus 8,0b10000000

  lc_conf 9, 0b00000001
  lc_conf 10,0b00000010
  lc_conf 11,0b00000100
  lc_conf 12,0b00001000

  cpi get,SO ;(Umschaltung (op call) ->run)
  brne PC + 2
  rjmp run

        ldi send,CAN
  rcall sendbyte

        rjmp end_int_rxd
;####################################################################### 
##########

run:
ldi send,'k'
rcall sendbyte
ldi send,ACK
rcall sendbyte
pop temp
out SREG,temp
cli
jmp main

>####################################################################### 
###########

wie ihr seht wird SREG wiederhergestellt bevor die messung beginnt, oder 
wenn der stop befehl kommt,...

ich werde mal nen flag einbasteln, so das das Interrupt nur kurz ist,...



von Sonic (Gast)


Lesenswert?

Grundsätzliches zum ADC beim mega32:

1. nach Umschalten des MUX min. 40µs bis zur Messung warten, beim
   Umschallten der Betriebsart (single-ended => differentiell) sogar 
120µs
2. Der mega32 misst differentiell auch negativ, das heißt, sobald das 
bit 1
   des ADCH gesetzt ist, ist das Ergebnis negativ. Datenblatt studieren!

In C hätte ich ein Beispiel, ASM leider nicht.

von Stefan K. (_sk_)


Lesenswert?

Toll. SREG wird klar gesichert. Und zwar in temp. Und was Dein main in 
temp gespeichert hat, ist jetzt verloren.

Der Wert in temp wird also sporadisch überschrieben - und zwar immer 
dann, wenn Dein IR dazwischengefunkt hat.

Wenn Du schon auf globale Variablen baust, dann solltest Du jedem 
Programmteil seine eigenen Variablen gönnen.

Das hängt wohl nicht mit deinem aktuellen ADC-Problem zusammen, trotzdem 
solltest Du Dir das mal ansehen.

Gruß, Stefan

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.