Forum: Mikrocontroller und Digitale Elektronik AtMega8 ADC: Funktioniert dieser Code?


von Roland N. (eroli)


Lesenswert?

Hallo zusammen,

ich versuche gerade den ADC am Controller zu testen. Dafür hab ich einen 
Helligkeitssensor wie im Tutorial beschrieben an PC0 angeschlossen. Mein 
Code zum testen sieht nun so aus:
1
.include "m8def.inc"  ;Die Definitionsdatei des ATmega8 einfügen.
2
3
.def temp     = R16  ;Arbeitsregister
4
5
rjmp RESET ; Reset Handler
6
reti  ; IRQ0 Handler
7
reti  ; IRQ1 Handler
8
reti  ; Timer2 Compare Handler
9
reti  ; Timer2 Overflow Handler  
10
reti  ; Timer1 Capture Handler
11
reti  ; Timer1 CompareA Handler
12
reti  ; Timer1 CompareB Handler
13
reti  ; Timer1 Overflow Handler
14
reti  ; Timer0 Overflow Handler
15
reti  ; SPI Transfer Complete Handler
16
reti  ; USART RX Complete Handler
17
reti  ; UDR Empty Handler
18
reti  ; USART TX Complete Handler
19
reti  ; ADC Conversion Complete Handler
20
reti  ; EEPROM Ready Handler
21
reti  ; Analog Comparator Handler
22
reti  ; Two-wire Serial Interface Handler
23
reti  ; Store Program Memory Ready Handler
24
25
reset:
26
ldi temp, LOW(RAMEND)  ;Initialisieren des StackPointers:
27
out SPL, temp
28
ldi temp, HIGH(RAMEND)
29
out SPH, temp
30
31
32
ldi temp, 0xFF      ;Arbeitsregister "temp" mit Einsern füllen.
33
out DDRB, temp      ;Datenrichtungsregister des Ports B mit Einsern aus "temp" füllen (= alle Pins des Ports als AUSGANG)
34
out PORTB, temp      ;Alle Pins des Ports auf's High-Level bringen
35
36
out DDRD, temp      ; Alle Pins von PortD als Ausgang festlegen
37
out PORTD, temp      ; Alle Pins auf HIGH setzen
38
39
ldi temp, 0
40
out DDRC, temp  ; Port C als Eingang
41
42
; ADC einstellen
43
ldi     temp, (1<<REFS0)                   ; Kanal 0, interne Referenzspannung 5V
44
out     ADMUX, temp
45
ldi     temp, (1<<ADEN) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0) | (1<<ADLAR)
46
out     ADCSRA, temp
47
48
49
sei    ;Interrupts freigeben
50
;------------------------------
51
52
; ============================ Hauptprogramm ============================
53
loop:  
54
sample_adc:
55
    sbi     ADCSRA, ADSC        ; den ADC starten
56
wait_adc:
57
    sbic    ADCSRA, ADSC        ; wenn der ADC fertig ist, wird dieses Bit gelöscht
58
    rjmp    wait_adc
59
60
    in      temp, ADCL         ; immer zuerst LOW Byte lesen
61
    in      temp, ADCH        ; danach das mittlerweile gesperrte High Byte
62
63
  cpi temp, 0x99        ; temp >= 0x99 --> higher else lower
64
  brge higher
65
  brlo lower
66
higher:
67
  ldi temp, 0xFF
68
  out PORTB, temp        ; LEDs an
69
  out PORTD, temp
70
  rjmp loop          ; Von vorne beginnen
71
lower:
72
  ldi temp, 0
73
  out PORTB, temp        ; LEDs aus
74
  out PORTD, temp
75
  rjmp loop          ; Von vorne beginnen
76
77
; ============================ Hauptprogramm Ende ============================

Und es sollte sich so verhalten: temp >= 0x99 --> higher else lower.
Aber irgendwie geht er immer in Higher?
Sieht jemand meinen Denkfehler?

Dankeschön :-)

von spess53 (Gast)


Lesenswert?

Hi

>    in      temp, ADCL         ; immer zuerst LOW Byte lesen
>    in      temp, ADCH        ; danach das mittlerweile gesperrte High Byte

Es reicht, ADCH einzulesen.

>  cpi temp, 0x99        ; temp >= 0x99 --> higher else lower
>  brge higher
>  brlo lower
>higher:

Das 'brge higher' kannst du weglassen. Wenn nicht nach 'lower' 
gesprungen, wird 'higher' eh ausgeführt. Außerdem ist 'brge' für 
vorzeichenbehaftete Werte.

MfG Spess

von Roland N. (eroli)


Lesenswert?

Hi,

hatte deine Antwort zu spät gelesen, nun ist mein Progrämmchen so:
1
loop:  
2
sample_adc:
3
    sbi     ADCSRA, ADSC        ; den ADC starten
4
wait_adc:
5
    sbic    ADCSRA, ADSC        ; wenn der ADC fertig ist, wird dieses Bit gelöscht
6
    rjmp    wait_adc
7
8
    in      temp, ADCH
9
10
  cpi temp, 0xFF        ; temp >= 0xFF --> higher else lower
11
  brsh higher
12
  ldi temp, 0          ; Lower:
13
  out PORTB, temp        ; LEDs aus
14
  out PORTD, temp
15
  rjmp loop          ; Von vorne beginnen
16
higher:
17
  ldi temp, 0xFF
18
  out PORTB, temp        ; LEDs an
19
  out PORTD, temp
20
  rjmp loop          ; Von vorne beginnen

Im Debugger funktioniert alles wunderbar, allerdings geht er in der 
Realität IMMER in den HIGHER-Zweig (egal ob ich den Schwellwert auf 0xFF 
(wie oben) oder auf 0x00) habe).
Das heißt doch, dass der ADC  immer 0xFF in mein temp schreibt, richtig?

von spess53 (Gast)


Lesenswert?

Hi

>Das heißt doch, dass der ADC  immer 0xFF in mein temp schreibt, richtig?

Sieht so aus. Hast du alle Versorgungsspannungen angeschlossen?

MfG Spess

P.S. Wozu ist 'sei    ;Interrupts freigeben' ?

von Roland N. (eroli)


Lesenswert?

Das "sei" ist nur ein Überbleibsel, sollte wohl aber nicht stören, oder?

Habe gerade nochmal nachgemessen, die Spannung an PC0 ändert sich jenach 
dem von 0.4V bis 3.4V. Das sollte doch eine ausreichend große Differenz 
sein, um sie irgendwie zu detektieren, oder?

Habe nun auch nochmal die Versorgungsspannungen nachgemessen.

AREF (21) und AVCC (20) liegen beide bei 5V. GND (22) ist auch vorhanden 
(VCC (7) und GND (8) sind natürlich auch da). Ist doch richtig, oder?

von spess53 (Gast)


Lesenswert?

Hi

>Das "sei" ist nur ein Überbleibsel, sollte wohl aber nicht stören, oder?

Nein.

>Ist doch richtig, oder?

Ja.

Hast du an den Ports B und D an allen Pins Leds? Wenn ja, dann gib doch 
mal den ADC-Wert dort aus.

MfG Spess

von Roland N. (eroli)


Lesenswert?

Ja, sind überall LEDs dran. Habe ich auch schon gemacht. Ergebnis: Alle 
LEDs leuchten... ???

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.