Forum: Mikrocontroller und Digitale Elektronik ADC mit ATMega16 (Assambler) Problem


von Fabi (Gast)


Lesenswert?

Hallo,

Ich hab ein problem mit einer einfachen Singel-Messunge des ADC vom 
ATMega16.
Ich verwendet eine STK500 und bin nun am ende meiner Kenntnisse.

Die erste messung wird durchgeführt aber jeder weitere hat den Wert der 
ersten. Ich hab im Tutorial hier gelesen das die werte übernohmen werden 
müssen, nur ich weiß nicht wie genau.

Vorgabe: es muss mit Assambler programmiert werden.

Hier ist mein programmcode... der leider nach der erste messung nichts 
mehr einliest.
1
.INCLUDE "M16def.inc"
2
3
;*********************************************************************************
4
;* Definitionen und Zuweisungen                                                  *
5
;*********************************************************************************
6
.DEF akku = r16
7
8
9
;*********************************************************************************
10
;* Interrupt Vektortabelle                                                       *
11
;*********************************************************************************
12
.CSEG
13
.ORG 0x000
14
RJMP MainInit
15
.ORG 0x01C
16
RJMP ADinterput
17
18
19
;*********************************************************************************
20
;* Main Initzialisierung                                                         *
21
;*********************************************************************************
22
MainInit:
23
24
;Stackinitialisierung:
25
LDI akku, HIGH(RAMEND)
26
OUT SPH, akku
27
LDI akku, LOW(RAMEND)
28
OUT SPL, akku
29
30
;Portzuweisung EINGÄNGE PORT A (Für Analoges Signal)
31
LDI akku, 0x00
32
OUT DDRA, akku
33
34
;Portzuweisung AUSGÄNGE PORT B
35
LDI akku, 0xFF
36
OUT DDRB, akku
37
out PORTB, akku
38
39
;Portzuweisung EINGÄNGE PORT D
40
LDI akku, 0x00
41
OUT DDRD, akku
42
43
;**********************************
44
;*    AD-Converter einstellen.    *
45
;**********************************
46
47
clr akku
48
49
;Teiler einstellen Vorteiler 8 und Wandler Aktiveren
50
;ldi akku, (1<<ADEN) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
51
LDI akku, 0b10000011
52
OUT ADCSRA, akku
53
54
;Kanal ADC0 Wählen und Refernspannung Nutzen
55
;ldi akku, (1<<REFS0) | (1<<REFS1)
56
ldi akku, 0b11000000
57
OUT ADMUX, akku 
58
59
;*********************************************************************************
60
;* MAINPROGRAMM                                                                  *
61
;*********************************************************************************
62
63
Mainloop:
64
  sbis PIND, PD0  ;Taste 0 gedrückt = Einzelmessung
65
  rcall EINZEL
66
  sbis PIND, PD1
67
  rcall CLEAR
68
rjmp mainloop
69
70
71
;*********************************************************************************
72
;* Unterprogramm Einzelmessung                                                   *
73
;*********************************************************************************
74
EINZEL:
75
  ;Messung starten
76
  sbi ADCSRA, ADSC
77
  ;Schleife für Messung fertig
78
warte:
79
  sbic ADCSRA, ADSC
80
  rjmp warte
81
  in akku, ADCL
82
  com akku
83
  OUT PORTB, akku
84
85
ret
86
87
;*********************************************************************************
88
;* Unterprogramm LEDs - Clear                                                    
89
;*********************************************************************************
90
CLEAR:
91
  ser akku
92
  OUT PORTB, akku
93
  com akku
94
  OUT ADCL, akku
95
  OUT ADCH, akku
96
ret
97
98
99
ADinterput:
100
  nop
101
reti

von Karl H. (kbuchegg)


Lesenswert?

rjmp warte
  in akku, ADCL
  com akku
  OUT PORTB, akku


Dann lies noch mal im Artikel nach, wie das ist, wenn man ein 16-Bit 
Register auslesen will. Man muss das High-Byte ebenfalls auslesen. Das 
Lesen des Low-Bytes verriegelt den ADC gegen Updates. Das Lesen des 
High-Bytes hebt diese Verriegelung wieder auf.

von Martin Meumann (Gast)


Lesenswert?

Ja ob jetzt acht bit oder doch sechzen bit die brauchbaren ergebnisse 
sind mehr oder weniger im Highbyte Register

von Fabi (Gast)


Lesenswert?

1
rjmp warte
2
  in akku, ADCL
3
  in akku, ADCH
4
  com akku
5
  OUT PORTB, akku

Nun sieht es folgend aus: hoffe das passt so, jedoch

aber das hat auch nichts gebracht, noch immer steht das ergebnis der 
ersten messung drin

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

jetzt liest du nur die oberen beiden Bit's des Messwertes aus, wenn du 
da eine Veränderung sehen willst muss die Eingangsspannung in größerem 
Maß geändert werden. Entweder die liest ADCH in ein anderes Register 
wenn du die oberen Bits nicht brauchst, oder du setzt ADLAR=1 im ADMUX 
dann sind die oberen 8-Bits im ADCH und die unteren 2 im ADCL.

Sascha

von Fabi (Gast)


Lesenswert?

wieso ich lese doch jetzt beide einmal aus... aber da ich 8 LED´s auf 
dem STK500 habe kann und will ich nur 8 anzeigen. die anzeige ist ja 
nicht mein problem nur das die neuen Werte geschrieben werden.

Wie müsste es aussehen damit es funktioniert?

von spess53 (Gast)


Lesenswert?

Hi

Mit welcher Frequenz läuft dein ATMega. Der Prescaler von 8 scheint mir 
etwas klein.

MfG Spess

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

ja - du liest beide aus, aber überschreibst den 1. Wert gelesenen Wert 
(ADC-Bit's 7..0) in deinem Register 'akku' wieder mit dem 2. Wert 
(ADC-Bit's 9..8). Wenn du ADCH nicht brauchst, dann lies den Wert nicht 
in 'akku' sondern in ein anderes Register ein! Oder schalte die 
Anordnung der Daten mit ADLAR=1 um.
Wenn du nur Bit 9 und 8 ausliest, dann ändert sich dort bei Vref=2.56V 
nur alle 0.64V was!
Spannung           Bit 9 8
< 0.64                 0 0
> 0.64 , < 1.28        0 1
> 1.28 , < 1.92        1 0
> 1.92                 1 1

Achso: das ...
>  OUT ADCL, akku
>  OUT ADCH, akku

... kannst du dir sparen, ADCL/ADCH sind Readonly !


Sascha

von Fabi (Gast)


Lesenswert?

Danke erstmal

Hab nun das ganz zum laufen gebracht.

die reihenfolge vom auslesen der ADC-Register ist wichtig.
Das mit in eine anderes register ist Richtig.
garnicht einlesen geht nicht und auch das umdrehen lässt keine
neuen Werte zu.

Zuerst muss das ADCL gelesen werden und erst danach das ADCH.
ins selbe Register speichern bewirkt wieder nichts, in zwei
seperate Register jedoch, lässt es zu und nun funktioniert auch alles.

Grüße

Als Anhang das funktionierde Programm

1
.INCLUDE "M16def.inc"
2
3
;*********************************************************************************
4
;Definitionen und Zuweisungen
5
;*********************************************************************************
6
.DEF akku = r16
7
.DEF akku2 = r17
8
9
10
;*********************************************************************************
11
;Interrupt Vektortabelle
12
;*********************************************************************************
13
.CSEG
14
.ORG 0x000
15
RJMP MainInit
16
.ORG 0x01C
17
RJMP ADinterput
18
19
20
;*********************************************************************************
21
;Main Initzialisierung
22
;*********************************************************************************
23
MainInit:
24
25
;Stackinitialisierung:
26
LDI akku, HIGH(RAMEND)
27
OUT SPH, akku
28
LDI akku, LOW(RAMEND)
29
OUT SPL, akku
30
31
;Portzuweisung EINGÄNGE PORT A (Für Analoges Signal)
32
LDI akku, 0x00
33
OUT DDRA, akku
34
35
;Portzuweisung AUSGÄNGE PORT B
36
LDI akku, 0xFF
37
OUT DDRB, akku
38
out PORTB, akku
39
40
;Portzuweisung EINGÄNGE PORT D
41
LDI akku, 0x00
42
OUT DDRD, akku
43
44
;**********************************
45
;*    AD-Converter einstellen.    *
46
;**********************************
47
48
clr akku
49
50
;Teiler einstellen Vorteiler 8 und Wandler Aktiveren
51
;ldi akku, (1<<ADEN) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
52
LDI akku, 0b10000011
53
OUT ADCSRA, akku
54
55
;Kanal ADC0 Wählen und Refernspannung Nutzen
56
;ldi akku, (1<<REFS0) | (1<<REFS1)
57
ldi akku, 0b11000000
58
OUT ADMUX, akku 
59
60
;*********************************************************************************
61
;MAINPROGRAMM
62
;*********************************************************************************
63
64
Mainloop:
65
  sbis PIND, PD0  ;Taste 0 gedrückt = Einzelmessung
66
  rcall EINZEL
67
  sbis PIND, PD1
68
  rcall CLEAR
69
rjmp mainloop
70
71
72
;*********************************************************************************
73
;Unterprogramm Einzelmessung
74
;*********************************************************************************
75
EINZEL:
76
  ;Messung starten
77
  sbi ADCSRA, ADSC
78
warte:
79
  sbic ADCSRA, ADSC
80
  rjmp warte
81
  in akku, ADCL
82
  in akku2, ADCH
83
  com akku
84
  OUT PORTB, akku
85
ret
86
87
88
;*********************************************************************************
89
;Unterprogramm LEDs - Clear
90
;*********************************************************************************
91
CLEAR:
92
  ser akku
93
  OUT PORTB, akku
94
ret
95
96
ADinterput:
97
  nop
98
reti

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.