Forum: Mikrocontroller und Digitale Elektronik AVR 4433 und ADC


von Felix (Gast)


Lesenswert?

Hallo an alle
ich hab jetzt schon zum dritten mal versucht, den adc in einem 4433 
vernünftig zum laufen zu bewegen, aber der will einfach nicht.
erstmal kurz den quellcode den ich nutze:

.include "d:\avr\4433def.inc"
.def temp=r16
.def temp1=r17
.def delay1=r18
.def delay2=r19

ldi temp, high(ramend)
out SP, temp
ldi temp,low(ramend)
out spl, temp

 ldi temp,0b10100110
 out ADCSR,temp
 ldi temp,0x01
 out ADMUX,temp ;Eingang AD0
 sbi ADCSR,ADSC ;StartADC im free run

 ser temp
 out ddrd, temp
 ldi temp, 0b00000011
 out ddrb, temp

loop_adc:

in temp,ADCL ; ADC lo
in temp1,ADCH ; ADC hi
rcall delay100
out portd, temp
out portb, temp1
rjmp loop_adc ;

delay100:
inc delay1
brne delay100ms
inc delay2
brne delay100ms
ret

wie man sieht eigentlich nix besonderes. der chip läuft mit 4 MHz und 
der prescaler steht auf 64, müsste eigentlich passen. das low-byte und 
das high-byte werden mit leds an den ports b und d ausgegeben.
Jedoch bekomme ich nur bit-geflimmer an port-d und port-b wenn ich am 
poti (spannungsteiler zwischen Vcc und Gnd) rumdrehe. und das auch nicht 
konstant. zum beispiel erscheinen die unteren vier bit des low-bytes 
erst ab ca 2,4 Volt (darunter alles null) und kurz bevor 5V an dem 
analogeingang anliegt fangen die restlichen bits an zu flackern (vorher 
sind die alle aus).
kann sich irgendwie jemand erklären, was da los ist, ich nämlich leider 
nicht mehr.
an verschiedenen stellen sind auch kondensatoren (100nF) zum glätten 
angebracht. die scheinen aber auch nix zu nützen.
ja wie gesagt, dies ist nun schon mein dritter versuch dem 4433 das 
ad-wandeln beizubringen, aber ich bin genauso weit wie beim ersten 
versuch. wahrscheinlich ist der chip, den ich hier habe, zu doof dafür, 
oder ich.
wenn jemand noch eine antwort weis, dann wäre ich dafür sehr dankbar.
ich wünsche alle noch einen schönen abend und gute nacht.
euer felix

von hebel23 (Gast)


Lesenswert?

Hallo Felix,
also erst mal ist so ein Chip natürlich immer so doof/schlau, wie sein 
Programmierer ;-) aber Spaß bei Seite.
Als erstes fällt mir auf, dass Du mit dem Befehl:

ldi temp,0x01
out ADMUX,temp ;Eingang AD0

...nicht Eingang AD0 sondern Eingang AD1 auf den ADC legst. Vielleicht 
siehst Du auf Deinen LED's nur das Floaten vom AD0 auf den AD1.
Ausserdem vermisse ich die Portkonfiguration für den ADC-Port.

ldi  Temp,0x11111110
out  DDRC,Temp    ; PortC(ADC) input

Weiterhin kann man zwar auf den ADC mit einem festen delay warten. 
Günstiger ist aber sicher immer den Interrupt abzufragen. So ist man 
immer so schnell, wie es geht und vergeudet keine Zeit und kann so auch 
immer sicher sein, dass der ADC fertig ist. Ich hab hier mal 2 Routinen, 
die bei mir funktionieren. Vielleicht probierst Du sie mal aus.

;***************************************************
; Initialisieren des ADC (nur einmal ausführen)
;***************************************************
ADC_init:
  ldi  Temp,0b00000000  ; Bandgap disable
  out  ADMUX,Temp
  ldi  Temp,0b10010111
  out  ADCSR,Temp      ; ADC enable
        ; start Konvert.
        ; Free run
        ; Int
        ; Int enable
        ; Prescaler
        ; ADCL Low Register
        ; ADCH High Register
  ret
;***************************************************
; ADC-Routine
; Temp enthält MUX-Wert
; Wandlerwert: op2_1:op2_2(dual)
;***************************************************
ADC:  out  ADMUX,Temp
  sbi  ADCSR,ADSC  ; Konvert. starten
wait:  sbis  ADCSR,ADIF  ; auf Konvert.warten
  rjmp  wait
  in  op2_2,ADCL  ; Lowbyte lesen
  in  op2_1,ADCH  ; Highbyte lesen
  sbi  ADCSR,ADIF
  ret
;***************************************************

Viele Grüße
Andreas

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.