Forum: Mikrocontroller und Digitale Elektronik Problem mit ADCs bei ATTINY 25


von Chris (Gast)


Lesenswert?

Hallo,

ich habe ein kleines Problem mit nem ATTINY25 und dessen ADCs.

An ADC1 (PB2) ist ein Poti angeschlossen. Gemessen werden soll hier die 
Batteriespannung die durch das Poti Werte zwischen 0V und 5V erreichen 
kann (das Poti Dient als Spannungsteiler und zum Justieren! 
Batteriespannung = 18V) Der Batteriestand wird angezeigt mittels roter 
LED (an PB0) und grüner LED (an PB1).

An ADC3 (PB3) hängt ebenfalls ein Poti. Hier liegen ebenfalls Spannungen 
zwischen 0V und 5V (5V sind die gleichen wie Vcc vom ATTINY) an. 
Hierüber soll die Poti-Stellung ermittelt werden und in eine 
Software-PWM umgewandelt werden (noch nicht im Code!). Mit der PWM 
sollen mittels FET LED-Streifen gedimmt werden.

Jetzt habe ich das Problem das das Poti an ADC3 die Werte von ADC1 
beeinflusst. Das äußert sich so, dass ein verändern von dem Poti, 
welches zum dimmen der LED-Streifen gedacht ist bei einem Schwellwert 
auch die LEDs der Batterieanzeige beeinflusst! Trotzdem funktioniert das 
Auslesen bei ADC3 und er Schaltet die LEDs beim Schwellwert (hier im 
Programm 0x50) ein.

Aber NUR wenn ich im Code beide ADCs anspreche. Lese ich nur ADC1 (der 
komplette Code für ADC3 ist gelöscht) aus kann ich das Dimm-Poti an ADC3 
bewegen wie ich will nix passiert! Erst das ändern der Batteriespannung 
führt zum unschalten der LED von Rot auf Grün und umgekehrt. So wie es 
sein soll.

Die Schaltung selbst ist ok und ob der LED-Streifen Leuchtet oder nicht 
ändert nichts am Ergebniss... Also schließe ich die Last als Störfaktor 
auch aus. Es kann eigentlich nur noch an der Software liegen.

Ich würde euch bitten mal einen Block drüber zu werfen. Bitte nicht 
sagen "das hätte man auch anders/effizienter Lösen können" mir geht hier 
im Moment nur um den oben beschriebenen Fehler!

Das hier ist bisher nur Testcode. Der Rest kommt später!

1
.def temp = r16          ;Definiert Registernamen
2
.def counter = r17
3
.def battery = r18
4
.def PWM = r19
5
.def PWM_value = r20
6
7
rjmp skip_interrupts;0x0000
8
nop          ;0x0001
9
nop          ;0x0002
10
nop          ;0x0003
11
nop          ;0x0004
12
nop          ;0x0005
13
nop          ;0x0006
14
nop          ;0x0007
15
nop          ;0x0008
16
nop          ;0x0009
17
rjmp timer      ;0x000A wird später benötigt!
18
nop          ;0x000B
19
nop          ;0x000C
20
nop          ;0x000D
21
nop          ;0x000E
22
23
skip_interrupts:
24
25
ldi temp,0xD0
26
out SPL,temp
27
28
ldi temp,(1<<ACD)              ; Schaltet Analogen Comperator aus
29
out ACSR,temp
30
31
32
ldi temp,(1<<DDB0) | (1<<DDB1) | (1<<DDB4)   ; Konfiguriert PortB,0 PortB,1 und PortB,4 als Ausgang
33
out DDRB,temp
34
        
35
ldi temp,(1<<CS00) | (0<<CS01) | (1<<CS02)  ;\
36
out TCCR0B,temp                             ; |  
37
                                            ; |
38
ldi temp,(1<<OCIE0A)                        ; |
39
out TIMSK,temp                              ;  \
40
                                            ;   - Counter wird erst später benötigt!
41
ldi temp,0x9C   ; = 156 Dez                 ;  /
42
out OCR0A,temp                              ; |
43
                                            ; |
44
clr temp                                    ; |
45
out TCNT0,temp                              ;/
46
47
rjmp start                  ; überspringe Counter-Interrupt
48
49
timer:                    ;\
50
                          ; |
51
clr temp                  ;  \ Counter-Interrupt Routine
52
out TCNT0,temp            ;  / Wird erst später benötigt!
53
                          ; |
54
reti                      ;/
55
56
start:                    ; hier beginnt das eigentliche Programm
57
58
cli                       ; Interrupts deaktieren da noch nicht gebraucht!
59
60
;--------------------------------------------------------------------------------------------
61
;Software - PWM Routine
62
; 
63
; - ADC3 (1<<MUX0) | (1<<MUX1)
64
; - Voltage Reference = Vcc => (0<<REFS0) | (0<<REFS1)
65
; - ADC Left Adjust Result => (1<<ADLAR)
66
;--------------------------------------------------------------------------------------------
67
68
PWM_request:
69
70
  ldi temp,(1<<MUX0) | (1<<MUX1) | (1<<ADLAR)  ; konfiguriert ADC
71
  out ADMUX,temp
72
  ldi temp,(1<<ADEN) | (1<<ADSC)        ; Startet Single Conversation
73
  out ADCSRA,temp
74
75
  PWM_wait:                  ; Warteschleife bis ADC fertig ist
76
77
    in temp,ADCSRA
78
    andi temp,0x10
79
    cpi temp,0x10              ; Prüfe ob ADIF Bit = 1
80
    brne PWM_wait              ; wenn nein nochma, wenn ja weiter
81
82
    in PWM_value,ADCH            ; Lese High-Wert ins PWM_value Register
83
84
    ldi temp,(1<<ADIF)            ; Resette ADIF Bit
85
    out ADCSRA,temp
86
87
    cpi PWM_value,0x50            ; Nur Test!!!
88
    brsh LEDs_on              ; Wenn Wert gleich oder größer 0x50 schalte LEDs ein
89
                    
90
    cbi PortB,4                ; Ansonsten schalte LEDs aus wenn Wert kleiner 0x50
91
92
    rjmp end_PWM            
93
94
    LEDs_on:
95
96
      sbi PortB,4              ; hier werden LEDs eingeschaltet!
97
98
end_PWM:
99
100
;--------------------------------------------------------------------------------------------
101
;Batterieprüfung
102
;
103
; - ADC1 (1<<MUX0)
104
; - Voltage Reference = Vcc => (0<<REFS0) | (0<<REFS1)
105
; - ADC Left Adjust Result => (1<<ADLAR)
106
;--------------------------------------------------------------------------------------------
107
108
batterycheck:
109
110
  ldi temp,(1<<MUX0) | (1<<ADLAR)        ; konfiguriert ADC
111
  out ADMUX,temp
112
  ldi temp,(1<<ADEN) | (1<<ADSC)        ; startet Single Conversation
113
  out ADCSRA,temp
114
115
  wait_bat:                  ; Wartet bis ADC fertig
116
117
    in temp,ADCSRA
118
    andi temp,0x10
119
    cpi temp,0x10              ; Prüfe ob ADIF Bit = 1
120
    brne wait_bat              ; wenn nein nochmal ansonsten weiter
121
122
    in battery,ADCH              ; liest den HIGH-Wert ins battery Register ein
123
124
    ldi temp,(1<<ADIF)            ; Resettet ADIF-Bit
125
    out ADCSRA,temp
126
127
    cpi battery,0x50            ; Nur Testwert!
128
    brsh green                ; Wenn Wert gleich oder größer 0x50 dann grüne LED
129
    cpi battery,0x50
130
    brlo red                ; Wenn Wert kleiner gleich 0x50 dann rote LED
131
    rjmp end_bat
132
133
    red:                  ; Schaltet grüne LED aus und rote LED ein
134
135
      cbi PortB,1
136
      sbi PortB,0
137
      rjmp end_bat
138
139
    green:                  ; Schaltet rote LED aus und grüne LED ein
140
141
      sbi PortB,1
142
      cbi PortB,0
143
144
end_bat:
145
146
  rjmp start                  ; starte Programm neu!

Ich hoffe ihr könnt mir helfen, ich verzweifel hier langsam :-(

von Klaus D. (kolisson)


Lesenswert?

mir würde sich ersteinmal die Frage stellen, wie hochohmig deine Potis
denn so sind, da es bei fehlerhafter Eingangsbeschaltung von ADC
zu gegenseitigen Beeinflussungen kommen kann.

Gruss Klaus

von spess53 (Gast)


Lesenswert?

Hi

Ich sehe keine Einstellungen für den ADC-Prescaler.

MfG Spess

von Knut (Gast)


Lesenswert?

die erste Messung einer Wandlung liefert keine richtigen Werte.

von spess53 (Gast)


Lesenswert?

Hi

>die erste Messung einer Wandlung liefert keine richtigen Werte.

Eine 'Wandlung' ist eine Messung. Wenn man deinen Satz darauf 
anwendet dürfte der ADC überhaupt keine richtigen Ergebnisse liefern.

Der erste gemessene Wert nach Ein-/Umstellung der 
Referenzspannungsquelle ist mit Vorsicht zu genießen. Ob das im 
Einzelfall überhaupt eine Rolle spielt, steht auf einem anderen Blatt.

MfG Spess

von Chris (Gast)


Lesenswert?

@spess53:

Der Division Factor ist 2 da die Bits ADPS0, ADPS1 und ADPS2 jeweils 0 
sind. Er misst ja auch, das ist nicht das Problem die zum generellen 
laufen zu bekommen. Alleine für sich funktionieren die Wunderbar nur 
zusammen nicht!

@Klaus de lisson:

an ADC1 zur Messung der Batteriespannung hängt ein 100k Präzissionspoti 
zwischen der Batteriespannung ca. 18V und GND. Eingestellt ist es im 
Moment so das ich bei 20V Batteriespannung 5V am ADC1 habe. An ADC3 
hängt ein 10k Faderpoti. zwischen 5V und GND. Die 5V sind die gleichen 
vom Spannungsregler an denen auch der Atmel hängt.
Abgegriffen wird bei beiden Potis jeweils über den Mittelkontakt.

von spess53 (Gast)


Lesenswert?

Hi

>Er misst ja auch, das ist nicht das Problem die zum generellen
>laufen zu bekommen. Alleine für sich funktionieren die Wunderbar nur
>zusammen nicht!

Wenn du meinst.

MfG Spess

von Chris (Gast)


Lesenswert?

ich habe die Initialisierung der ADCs nochmal wie folgt verändert:

ADC1:
1
ldi temp,(1<<MUX0) | (1<<ADLAR)        ; konfiguriert ADC
2
out ADMUX,temp
3
ldi temp,(1<<ADEN) | (1<<ADSC)   | (0<<ADPS0) | (0<<ADPS1) | (0<<ADPS2)   ; startet Single Conversation
4
out ADCSRA,temp

ADC3:
1
ldi temp,(1<<MUX0) | (1<<MUX1) | (1<<ADLAR)  ; konfiguriert ADC
2
out ADMUX,temp
3
ldi temp,(1<<ADEN) | (1<<ADSC) | (0<<ADPS0) | (0<<ADPS1) | (0<<ADPS2)  ; Startet Single Conversation
4
out ADCSRA,temp

Also den Prescaler fest auf 2 gesetzt, das Ergebnis ist das gleiche wie 
zuvor. Oder meintest du er sollte höher gesetzt werden?!

von spess53 (Gast)


Lesenswert?

Hi

> Oder meintest du er sollte höher gesetzt werden?!

Ja. Das Problem ist nicht die eigentliche Wandlung. Aber beim Umschalten 
der Kanäle muss auch der Sample&Hold-Kondensator umgeladen werden. Und 
das geht nicht unendlich schnell. Je kürzer die Zeit ist, um so mehr 
beeinflussen sich die Kanäle.

Du hast auch nicht die Frage
Beitrag "Re: Problem mit ADCs bei ATTINY 25"
beantwortet.

>| (0<<ADPS0) | (0<<ADPS1) | (0<<ADPS2)

Ist unsinnig:  X | 0 ist immer X

MfG Spess

von Chris (Gast)


Lesenswert?

> Du hast auch nicht die Frage
> Beitrag "Re: Problem mit ADCs bei ATTINY 25"
> beantwortet.
>
>>| (0<<ADPS0) | (0<<ADPS1) | (0<<ADPS2)
>
> Ist unsinnig:  X | 0 ist immer X
>
> MfG Spess

Hallo,

doch die Frage von Klaus de lisson habe ich heute morgen in meinem 
ersten Post beantowrtet.

Du hattest recht, mit Division Factor 8 läufts. Vielen Dank!

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.