ADC mit ATMega16 (Assambler) Problem

Gast #1299294
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
#1299578
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
#1299646
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
Gast #1299979
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren