Forum: Mikrocontroller und Digitale Elektronik Attiny13 ADC Probleme


von Tiny (Gast)


Lesenswert?

Hallo,
Ich probiere gerade den ADC ans laufen zu kriegen, klappt leider nicht 
so wie gedacht ;)
Ich hoffe ihr konnt mir bei meinem kleinen Problem helfen.
1
.include "tn13def.inc"
2
    ldi r16, 0b11101111
3
    out DDRB, r16
4
    ldi r16, 0b00001000
5
    out PORTB, r16
6
    ldi r16, 0b01100010
7
    out ADMUX, r16
8
    ldi r16, 0b11000101
9
    out ADCSRA, r16
10
11
12
    ldi r16, 0b00000000
13
schleife:    cp r5, r16
14
    breq schleife
15
  
16
17
18
    ldi r16, 0b00000000
19
    out PORTB, r16
20
21
22
ende:   rjmp ende


Das kleine Programm soll eigentlich nur überprüfen ob der ADC überhaupt 
einen Wert ungleich Null ins Register 5 ( ADCH ) ablegt, und wenn ja 
eine LED anschalten. Als Eingang für den ADC hab ich einen 
Spannungsteiler aus einem Widerstand 100kohm und einem LDR.
Na ja, es klappt halt nicht, der Inhalt von r5 bleibt konstand 0. Wo ist 
der Fehler?

von Karl H. (kbuchegg)


Lesenswert?

Tiny schrieb:


> Das kleine Programm soll eigentlich nur überprüfen ob der ADC überhaupt
> einen Wert ungleich Null ins Register 5 ( ADCH ) ablegt,

>     ldi r16, 0b00000000
> schleife:    cp r5, r16
>     breq schleife

also noch unverständlicher kann man das nun wirklich nicht schreiben.
Und nein, das vergleicht nicht, ob das Register ADCH jemals ungleich 0 
wird. r5 ist nicht ADCH

Lies doch bitte im AVR-Tutorial über den ADC nach. Im Tiny 13 
funktioniert zwar die Einstellung der Referenzspannung im Detail ein 
wenig anders, aber das Prinzip ist trotzdem identisch.

von Hannes L. (hannes)


Lesenswert?

@Tiny:

Tip: Die CPU-Register (r0 bis r31) und die I/O-Register sind Zweierlei.

...

von Tiny (Gast)


Angehängte Dateien:

Lesenswert?

Vielen Dank erstmal für eure Hilfe. Ich hab noch weiter gemacht, aber es 
klappt leider immer noch nicht.
1
include "tn13def.inc"
2
  ldi r16, 0b11101111
3
  out DDRB, r16
4
  ldi r16, (1<<REFS0) | (1<<ADLAR) | (1<<MUX1) 
5
  out ADMUX, r16
6
  ldi r16, (1<<ADEN) |  (1<<ADPS2) | (1<<ADPS0)
7
  out ADCSRA, r16
8
  sbi ADCSRA, ADSC
9
schleife:  sbic ADCSRA, ADSC
10
  brne schleife 
11
12
  ldi r16, ADCH
13
  cpi r16, 100   ; Schwellwert
14
  brlo aus
15
16
  ldi r16, 0b00001000
17
  out PORTB, r16
18
  rjmp ende
19
20
aus:  ldi r16, 0b00000000
21
  out PORTB, r16
22
ende:  rjmp ende

Was Cih machen möchte ist folgendes. Die LED soll je nach Lichteinfaall 
an oder aus geschaltet werden. Für den Schwellwert hab schon viele Werte 
ausprobiet und habe entdeckt, dass ADCH immer 5 ist. Egal ob ich den 
Finger auf den LDR halte oder nicht.
Ich sehe einfach nicht, was ich falsch machen. Vielleicht fällt einem 
von euch der Fehler auf.
Vielen Dank im Vorraus.

von Spess53 (Gast)


Lesenswert?

Hi

>Für den Schwellwert hab schon viele Werte
>ausprobiet und habe entdeckt, dass ADCH immer 5 ist.

Wie?

Und du weißt auch, das dein Programm nach maximal ein paar ms, eher 
wesentlich weniger, nichts mehr macht?

MfG Spess

von Tiny (Gast)


Lesenswert?

Schwellwert im Quellcode geändert, neu kompiliert, auf den mc gezogen 
und wieder laufen lassen. Ist der Wert kleiner 5 Leuchtet die LED, bei 
größeren Werten nicht.
Das das Programm erstmal nicht viel macht ist mir schon klar, entweder 
leuchtet die LED am Ende oder nicht. Wenn das mit dem ADC so klappt wie 
ich mir das denke kommt da natürlich noch eine Schlaife rum.

von Karl H. (kbuchegg)


Lesenswert?

Zieh die Schleife gleich rundum.
Ohne kannst du doch gar nicht vernünftig testen.


vor dem
  sbi ADCSRA, ADSC
machst du ein Label rein
1
  ...
2
  out ADCSRA, r16
3
loop:
4
  sbi ADCSRA, ADSC
5
schleife:  sbic ADCSRA, ADSC
6
  ...

und aus dem
1
    rjmp ende
machst du ein
1
    rjmp loop

fertig.

Finger auf den LDR, die LED muss umschalten.
Finger weg, die Led muss wieder zurückgehen.

Welchen Wert hat dein RL?

von Karl H. (kbuchegg)


Lesenswert?

Ähm.
Hast du der LED keinen Vorwidertand spendiert?

von Tiny (Gast)


Lesenswert?

Vorwiderstand ist dran, hab ich nur vergessen einuzeichnen. Zu den 
anderen Widerstandswerten: (ich glaube das war mit LD gemeint?)

R1: 10kohm
R2: 100kohm
LDR: 1kohm unter der Lampe 200kohm mit Finger drauf

von Karl H. (kbuchegg)


Lesenswert?

Ach das ist ein 2-er und kein L
Tschuldigung, konnte ich nicht identifizieren.

d.h. mit Finger drauf hast du einen Spannungsteiler 100k-200k, das sind 
dann ca. 3.6V am ADC Pin (mit Voltmeter nachmessen).
Und wenn die Lampe draufscheint sind das 100k-1k, also praktisch 0V.

Das sollte sich im ADC Wert bemerkbar machen. Schwellwert so ungefähr 
100 müsste gehen. Wobei man der ersten Messung des ADC nach dem 
Einschalten (angeblich) nicht so ganz trauen kann (daher auch die 
Schleife)

von Karl H. (kbuchegg)


Lesenswert?

Warum benutzt du die interne Referenz?
Lass doch den ADC die Versorgungsspannung als Referenz nehmen!

von Tiny (Gast)


Lesenswert?

Sp folgendes hab ich jetzt gemacht:
-Schleife ist drum
-Vcc ist als Referenz eingestellt
- Ich hab zwischen dem ADC Pin und GND gemessen. 0.54V im Hellen, 2.6 
mit Finger drauf.
- hab nen anderen attiny13 genommen, ergebniss bleibt gleich

Hab wieder diverse Schwellwerte ausgetestet. ADCH bleibt bei 5

von Karl H. (kbuchegg)


Lesenswert?

Nochmal das Programm, bitte

(SChön langsam bin ich auch mit meinem Latein am Ende :-)

von Karl H. (kbuchegg)


Lesenswert?

Hier

schleife:  sbic ADCSRA, ADSC
  brne schleife

Der brne gehört da nicht hin. Das muss ein ganz normaler rjmp sein

von Tiny (Gast)


Lesenswert?

Hier bitte :)
1
include "tn13def.inc"
2
  ldi r16, 0b11101111
3
  out DDRB, r16
4
  ldi r16, (0<<REFS0) | (1<<ADLAR) | (1<<MUX1) 
5
  out ADMUX, r16
6
  ldi r16, (1<<ADEN) |  (1<<ADPS2) | (1<<ADPS0)
7
  out ADCSRA, r16
8
  loop:
9
  sbi ADCSRA, ADSC
10
schleife:  sbic ADCSRA, ADSC
11
  brne schleife 
12
13
  ldi r16, ADCH
14
  cpi r16, 100; Schwellwert
15
  brlo aus
16
17
  ldi r16, 0b00001000
18
  out PORTB, r16
19
  rjmp ende
20
21
aus:  ldi r16, 0b00000000
22
  out PORTB, r16
23
ende:  rjmp loop

von Tiny (Gast)


Lesenswert?

Ach ja, im Schaltplan hab ich eine Verbindung durchgestrichen (von der 
Diode zu Pin 1 ) Da ist auch wirklich keine!

von Karl H. (kbuchegg)


Lesenswert?

OK. Ändere den brne noch auf einen rjmp.
Jetzt seh ich auch nichts mehr im Programm, was mich stutzig machen 
würde. Die Konfig-Register hab ich mit dem Datenblatt gecheckt. Sind m.M 
nach vernünftig.

von Karl H. (kbuchegg)


Lesenswert?

Doch

Da seh ich noch was


   ldi r16, ADCH

das geht so nicht.
Das erklärt auch, wo deine 5 herkommen :-)
ldi (LoaD Immediate) wird benutzt um einen konstanten Zahlenwert in ein 
Register zu laden. In deinem Fall, ist das dann die Adresse vom Register 
ADCH. Das willst du aber nicht. Du willst den Inhalt von ADCH! Und weil 
ADCH zu den I/O Registern gehört:

   in   r16, ADCH

von Tiny (Gast)


Lesenswert?

Ja, das wars! Funktioniert!
Vielen dank für deine ausdauernde Hilfe! :)
Deine Erklärung leuchtet auch ein. 0x05 ist ja Die Adresse von ADCH

von Karl H. (kbuchegg)


Lesenswert?

Tiny schrieb:
> Vielen dank für deine ausdauernde Hilfe! :)

gern geschehen

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.