Problem mit ADCs bei ATTINY 25

Gast #2108340
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 :-(
Gast #2108418
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
Gast #2108493
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.
Gast #2108518
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?!
Gast #2108526
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
Gast #2108559
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!

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