Forum: Mikrocontroller und Digitale Elektronik Atmega88 ADC Assembler Problem


von A. B. (developer_x)


Lesenswert?

Sehr geehrtes Forum,
ich nutze folgenden Code, und leider
ist stets dieselbe LED, grün, angeschaltet.

Ich habe am ATMega direkt am Pin PC0 gemessen, ob die Spannung ankommt,
und folgende Verschaltung:
AVCC, mit VCC verbunden, AREF, an GND

Code:
1
.include "m88def.inc" // Definitionsdatei für den Prozessortyp einbinden
2
3
/*
4
5
  Es soll die Spannung des Potentiometers gemessen werden,
6
  und anschließend geprüft werden, in welchem Bereich die Spannung liegt.
7
  
8
  Liegt sie in der unteren Hälfte, so leuchtet die rote LED,
9
  liegt sie in der oberen Hälfte, so leuchtet die grüne LED
10
11
*/
12
13
.CSEG // Programm Code für den Flash Speicher
14
15
//  Konstante definieren
16
.equ SCHWELLENWERT = 128
17
18
// Richtung der IO Ports definieren
19
LDI R16, 0b11111111    // 1=Output, 0=Input
20
OUT DDRD, R16
21
22
// Stackpointer initialisieren
23
LDI R16, low(RAMEND)
24
OUT SPL, R16
25
LDI R16, high(RAMEND)
26
OUT SPH, R16
27
28
// Main Methode
29
MAIN:
30
//  ADC Initialsieren
31
  RCALL ADC_INIT
32
  
33
//  Spannung an Potentiometer einstellen
34
  CBI PORTD, PIND2
35
36
  MAIN_LOOP:
37
  //  Warte
38
    CBI PORTD, PIND2
39
    RCALL WAIT_SEC
40
41
  //  Messung starten
42
    RCALL ADC_MEASURE
43
44
  //  Prüfung
45
    CPI  R16, SCHWELLENWERT // Vergleiche R17 mit Schwellenwert
46
    BRLO ROT_ANSCHALTEN
47
    
48
    GRUEN_ANSCHALTEN:
49
    SBI PORTD, PD1  // GRUEN Anschalten, falls größer
50
    CBI PORTD, PD0    
51
52
    RJMP FERTIG
53
54
    ROT_ANSCHALTEN:  // ROT Anschalten, falls kleiner
55
    SBI PORTD, PD0
56
    CBI PORTD, PD1
57
58
    FERTIG:
59
60
  //  Warte
61
    RCALL WAIT_SEC
62
63
  RJMP MAIN_LOOP
64
RJMP MAIN
65
66
// ADC Initialisieren
67
ADC_INIT:
68
  //  Kanal 0, mit Interner Referenzspannung AVCC auswählen
69
  LDI R16, (1<<REFS0)// | (1<<ADLAR)
70
  STS ADMUX, R16
71
72
  // ADC   einschalten,     und Messfrequenz einstellen
73
  LDI R16, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
74
  STS ADCSRA, R16
75
RET
76
77
// Messung durchführen
78
ADC_MEASURE:
79
  //  Beginnen  
80
  LDS R16, ADCSRA
81
  SBR R16, ADSC
82
  STS ADCSRA, R16
83
84
  //  SBI ADCSRA, ADSC   // AD Start Conversion Bit gesetzt
85
     // funktioniert nicht, da SBI hier out of range
86
87
  // Warten bis Messung beendet
88
  ADC_MEASURE_WAIT:
89
    LDS R16, ADCSRA
90
    SBRC R16, ADSC  // Prüfen ob Bit entfernt wurde, wenn, dann ist Messung fertig
91
    RJMP ADC_MEASURE_WAIT
92
93
  SBI PORTD, PIND2
94
95
  // Messungsdaten auslesen
96
  LDS R16, ADCL
97
  LDS R17, ADCH  
98
RET
99
100
WAIT_SEC:
101
  LDI R21,255
102
103
  WAIT_SEC_22:
104
  RCALL WAIT_SEC_2
105
  DEC R21
106
  BRNE WAIT_SEC_22
107
RET
108
109
WAIT_SEC_2:
110
  LDI R20,255
111
112
  WAIT_SEC_21:
113
  RCALL WAIT_SEC_1
114
  DEC R20
115
  BRNE WAIT_SEC_21
116
RET
117
118
WAIT_SEC_1:
119
  NOP
120
  NOP
121
  NOP
122
  NOP
123
  NOP
124
  NOP
125
  NOP
126
  NOP
127
  NOP
128
  NOP
129
RET

Danke für eine Antwort,
m.f.G.: Developer_X

von Walter S. (avatar)


Lesenswert?

K. R. schrieb:
> AREF, an GND

Aref darf nicht an GND angeschlossen werden,

ansonsten musst du auf unseren ASM-Spezialisten warten
(Moby hilf)

von A. B. (developer_x)


Lesenswert?

Ich hab das mit AREF schon in verschiedensten Variationen getestet, mal 
an GND, mal an VCC, mal mit Kapazität an GND, nichts hilft.

Die rote LED funktioniert übrigstens auch, falls das jemand fragen will.
Es muss mehr am Code liegen.

von Peter II (Gast)


Lesenswert?

LDS R17, ADCH

und dann vergleichst du R17 mit 128

aber kann denn das High Byte überhaupt so gross werden?

von Karl H. (kbuchegg)


Lesenswert?

K. R. schrieb:

> mal mit Kapazität an GND

das ist die richtige Variante. Vom ARef Pin ein Kondensator nach GND.


> Die rote LED funktioniert übrigstens auch, falls das jemand fragen will.
> Es muss mehr am Code liegen.

Wie ist dein Poti angeschlossen?

Was ist am Pin D2 angeschlossen?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> LDS R17, ADCH
>
> und dann vergleichst du R17 mit 128
>
> aber kann denn das High Byte überhaupt so gross werden?

Ja.
Er hat ADLAR gesetzt.

von Walter S. (avatar)


Lesenswert?

K. R. schrieb:
> Ich hab das mit AREF schon in verschiedensten Variationen getestet, mal
> an GND, mal an VCC, mal mit Kapazität an GND, nichts hilft.

bei entsprechender Einstellung der Ref-Spannung hast du damit die 
interne Rferenz ganz schön geqält, ob sie das überlebt hat ist die Frage

von A. B. (developer_x)


Lesenswert?

Ich seh gerade, der Code den ich gepostet hab war nciht der richtige.

Ich habe ADLAR gesetzt, und vergleiche R17


Die hab ich nicht gequält, ich arbeite mit 2,9V xd

von A. B. (developer_x)


Lesenswert?

Damit keine Missverständnisse entstehen, hier der Code:
1
.include "m88def.inc" // Definitionsdatei für den Prozessortyp einbinden
2
3
/*
4
  ADC_ATMEGA_88 Test
5
  30.09.2015
6
7
  2 LEDs und ein Potentiometer angeschlossen
8
9
  Referenzspannung für den ADC ist die AVCC
10
11
  Es soll die Spannung des Potentiometers gemessen werden,
12
  und anschließend geprüft werden, in welchem Bereich die Spannung liegt.
13
  
14
  Liegt sie in der unteren Hälfte, so leuchtet die rote LED,
15
  liegt sie in der oberen Hälfte, so leuchtet die grüne LED
16
17
*/
18
19
.CSEG // Programm Code für den Flash Speicher
20
21
//  Konstante definieren
22
.equ SCHWELLENWERT = 128
23
24
// Richtung der IO Ports definieren
25
LDI R16, 0b11111111    // 1=Output, 0=Input
26
OUT DDRD, R16
27
28
// Stackpointer initialisieren
29
LDI R16, low(RAMEND)
30
OUT SPL, R16
31
LDI R16, high(RAMEND)
32
OUT SPH, R16
33
34
// Main Methode
35
MAIN:
36
//  ADC Initialsieren
37
  RCALL ADC_INIT
38
  
39
//  Spannung an Potentiometer einstellen
40
  CBI PORTD, PIND2
41
42
  MAIN_LOOP:
43
  //  Warte
44
    CBI PORTD, PIND2
45
    RCALL WAIT_SEC
46
47
  //  Messung starten
48
    RCALL ADC_MEASURE
49
50
  //  Prüfung
51
    CPI  R17, SCHWELLENWERT // Vergleiche R17 mit Schwellenwert
52
    BRLO ROT_ANSCHALTEN
53
    
54
    GRUEN_ANSCHALTEN:
55
    SBI PORTD, PD1  // GRUEN Anschalten, falls größer
56
    CBI PORTD, PD0    
57
58
    RJMP FERTIG
59
60
    ROT_ANSCHALTEN:  // ROT Anschalten, falls kleiner
61
    SBI PORTD, PD0
62
    CBI PORTD, PD1
63
64
    FERTIG:
65
66
  //  Warte
67
    RCALL WAIT_SEC
68
69
  RJMP MAIN_LOOP
70
RJMP MAIN
71
72
// ADC Initialisieren
73
ADC_INIT:
74
  //  Kanal 0, mit Interner Referenzspannung AVCC auswählen
75
  LDI R16, (1<<REFS0) | (1<<ADLAR)
76
  STS ADMUX, R16
77
78
  // ADC   einschalten,     und Messfrequenz einstellen
79
  LDI R16, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
80
  STS ADCSRA, R16
81
RET
82
83
// Messung durchführen
84
ADC_MEASURE:
85
  //  Beginnen  
86
  LDS R16, ADCSRA
87
  SBR R16, ADSC
88
  STS ADCSRA, R16
89
90
  //  SBI ADCSRA, ADSC   // AD Start Conversion Bit gesetzt
91
     // funktioniert nicht, da SBI hier out of range
92
93
  // Warten bis Messung beendet
94
  ADC_MEASURE_WAIT:
95
    LDS R16, ADCSRA
96
    SBRC R16, ADSC  // Prüfen ob Bit entfernt wurde, wenn, dann ist Messung fertig
97
    RJMP ADC_MEASURE_WAIT
98
99
  SBI PORTD, PIND2
100
101
  // Messungsdaten auslesen
102
  LDS R16, ADCL
103
  LDS R17, ADCH  
104
RET
105
106
WAIT_SEC:
107
  LDI R21,255
108
109
  WAIT_SEC_22:
110
  RCALL WAIT_SEC_2
111
  DEC R21
112
  BRNE WAIT_SEC_22
113
RET
114
115
WAIT_SEC_2:
116
  LDI R20,255
117
118
  WAIT_SEC_21:
119
  RCALL WAIT_SEC_1
120
  DEC R20
121
  BRNE WAIT_SEC_21
122
RET
123
124
WAIT_SEC_1:
125
  NOP
126
  NOP
127
  NOP
128
  NOP
129
  NOP
130
  NOP
131
  NOP
132
  NOP
133
  NOP
134
  NOP
135
RET

von Karl H. (kbuchegg)


Lesenswert?

K. R. schrieb:

> Die hab ich nicht gequält


Natürlich hast du sie gequält.
Wenn die interne Referenzsoannungserzeugung eigeschaltet wird und ihre 
erzeugte Spannung auf den Pin ausgibt, dann kannst du den Pin nicht 
direkt mit GND verbinden. So etwas nennt man gemein hin einen 
Kurzschluss.

von S. Landolt (Gast)


Lesenswert?

> SBR R16, ADSC
Sollte heißen  SBR R16,(1<<ADSC)

von A. B. (developer_x)


Lesenswert?

S. Landolt schrieb:
> Sollte heißen  SBR R16,(1<<ADSC)

Das wars! Danke Landolt

Karl H. schrieb:
> Natürlich hast du sie gequält.
> Wenn die interne Referenzsoannungserzeugung eigeschaltet wird und ihre
> erzeugte Spannung auf den Pin ausgibt, dann kannst du den Pin nicht
> direkt mit GND verbinden. So etwas nennt man gemein hin einen
> Kurzschluss.

^^. Wenn du wüsstest was ich schon alles gemacht hab, da is nie was 
passiert xd, ich weiß dass das n Kurzschluss ist xd, aber da fliessen so 
geringe ströme bei den spannungen bei denen ich arbeite, da bassiert 
nöscht.

Viele Dank für eure Hilfe!
m.f.G.: Developer_X

von c-hater (Gast)


Lesenswert?

K. R. schrieb:

> Karl H. schrieb:
>> Natürlich hast du sie gequält.
>> Wenn die interne Referenzsoannungserzeugung eigeschaltet wird und ihre
>> erzeugte Spannung auf den Pin ausgibt, dann kannst du den Pin nicht
>> direkt mit GND verbinden. So etwas nennt man gemein hin einen
>> Kurzschluss.
>
> ^^. Wenn du wüsstest was ich schon alles gemacht hab, da is nie was
> passiert xd, ich weiß dass das n Kurzschluss ist xd, aber da fliessen so
> geringe ströme bei den spannungen bei denen ich arbeite, da bassiert
> nöscht.

Klar, es geht nichts kaputt. Aber du misst nur noch Mist, weil die 
Referenzspannung dann halt 0V (oder sehr, sehr nahe daran) ist.

Kann mal bitte irgendwer einen Hammer holen, damit wir diesen simplen 
Fakt allerunterster Trivialitätsstufe irgendwie in deinen völlig 
merkbefreiten Schädel gehämmert bekommen können?

von Michael U. (amiga)


Lesenswert?

Hallo,

K. R. schrieb:
> ^^. Wenn du wüsstest was ich schon alles gemacht hab, da is nie was
> passiert xd, ich weiß dass das n Kurzschluss ist xd, aber da fliessen so
> geringe ströme bei den spannungen bei denen ich arbeite, da bassiert
> nöscht.

Um diesen Deinen Satz zu interpretieren:
ich kann also eine Zelle meiner Autobatterie einfach kurzschließen?
Die 2V sind ja noch weniger als Deine 2,9V, da passiert also nichts?

Bei Aussagen wie obigen neige ich auch zum Hammer...

Gruß aus Berlin
Michael

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.