Forum: Mikrocontroller und Digitale Elektronik Einfache PWM mit Spannung ADC steuern (Attiny13)


von Fr00sch (Gast)


Lesenswert?

Hallo,
ich bin neu im Bereich Mikrocontroller und habe mir ein Programm für den 
Attiny13 geschrieben das abhängig von der anliegenden Spannung über den 
ADC das verhältnis von LOW und HIGH des PWMs einstellt:

1
.include "tn13def.inc"
2
3
4
rjmp   Anfang
5
Anfang:
6
;Pins belegen
7
      ldi r16, 0b11111111
8
      out DDRB,r16
9
      ldi r16, 0x00
10
      out PORTB,r16
11
   
12
;ADC initialisieren
13
      ldi    r16, 0b00100010
14
    out    ADMUX, r16
15
    ldi    r16, 0b11000111
16
    out    ADCSRA, r16
17
18
 
19
Schleife:
20
      sbi    portb,0
21
adc0_wait:
22
    sbic   ADCSRA,ADSC
23
    rjmp   adc0_wait
24
    in     r18, ADCL
25
    in     r17, ADCH
26
    ldi    r16,255
27
    sub    r16,r17
28
Warten1:
29
      dec    r17
30
    brne   Warten1
31
    cbi    portb,0
32
Warten2:
33
      dec    r16
34
    brne   Warten2
35
rjmp Schleife

Nun habe ich das Problem, wenn ich ein 1MOhm-Poti anschließe, ändert 
sich die Helligkeit der Led nur wenn ich es voll in Einrichtung drehe 
und auch nur auf etwa 50%, wenn ich aber ein 500Ohm-Poti anlegen dann 
lässt sich die Led wunderschön von etwa 90% bis 0% dimmen.
Ich verstehe im Moment nicht so richtig das Problem, weil normalerweise 
ja ein größerer Poti die Schaltung weniger beeinflusst. Könnte es vllt 
sein das irgendein Pullup- oder pulldown-widerstand am Eingang 
eingeschaltet ist und somit das Poti die Spannung nicht alleine 
beeinflusst?

Ich hoffe ihr könnt mir weiterhelfen und falls ich noch mit 
irgendwelchen Infos helfen kann, einfach bescheid sagen.

Gruß Fr00sch

von Jo (Gast)


Lesenswert?

Du musst den Pullup des ADCs ausschalten. Und nimm kein Poti größer
5k. Warum, kannst du aus dem Datenblatt schön ersehen.

SG Jo

von Mahnel (Gast)


Lesenswert?

Hallo,

Auch wenn ich mit der ADC nicht sooo auskenne, würde ich mal behaupten 
das Dein Problem darin begründet ist, das Du zuerst ALLE PBx als 
Ausgänge definierst. Der ADC kann trotzdem werte von den Ports einlesen, 
aber Dein Poti muss "gegen" den Port, der als Ausgang geschaltet ist und 
damit Strom (bis 60mA!) liefert, "anarbeiten".
Über den 1MOhm Poti lacht der Augang nur, damit wirst Du kaum 
Spannungsänderung erziehlen.

Mein Vorschlag wäre: (zumal im Programm später eh nur PB0 geschaltet 
wird)

;Pins belegen
      ldi r16, 0b00000001
      out DDRB,r16
      ldi r16, 0x00
      out PORTB,r16

Habs nicht Probiert, klingt aber Plausibel...

Bis dann und viel Glück (!)  =^.^=

von Fr00sch (Gast)


Lesenswert?

danke erstmal für die schnelle Antwort


Ich weis aber nicht wie ich ihn abschalte... am anfang definiere ich 
portB als Ausgang
1
ldi r16,0b11111111
2
out DDRB,r16
und gebe allen Pins keinen pullup
1
ldi r16, 0x00
2
out PORTB,r16
und im späteren verlauf definiere ich einen ausgang als adc-eingang ... 
meiner theorie nach müsste jetzt dort ein eingang ohne pullup sein, aber 
ist anscheinend nicht so ...

kann ich die pullups per MCUCR abschalten wieder?

ich hab nichts über einen 5k-Poti gefunden im Datenblatt,unter welcher 
rubrik soll das stehen?

von Hc Z. (mizch)


Lesenswert?

Außerdem sollte das zum ADC-Input gehörige DIDR0-Bit gesetzt sein, um 
Querstöme zu vermeiden.  Siehe Datenblatt.

von Hc Z. (mizch)


Lesenswert?

> am anfang definiere ich
> portB als Ausgang
> ....
> und im späteren verlauf definiere ich einen ausgang als adc-eingang ...
> meiner theorie nach müsste jetzt dort ein eingang ohne pullup sein, aber
> ist anscheinend nicht so ...

Das ist nur Deine Theorie.  Der Ausgang bleibt Ausgang.  Abhilfe ist, 
ihn gleich gar nicht als solchen zu definieren.

von Fr00sch (Gast)


Lesenswert?

Das klingt logisch Mahnel und habe ich auch schon probiert, aus 
irgendeinem Grund gabs da aber Probleme, werds heute abend nochmal 
probieren und mich dann nochmal melden.

Zum Thema Poti habe ich was gefunden im Datenblatt:
Auf Seite 120 Thema 18.7 ADC Chrakteristiken steht unter Analog Input 
Resistance: 1MOhm

von Hc Z. (mizch)


Lesenswert?

> Zum Thema Poti habe ich was gefunden im Datenblatt:
> Auf Seite 120 Thema 18.7 ADC Chrakteristiken steht unter Analog Input
> Resistance: 1MOhm

Es lässt sich in 14.8 auch Folgendes finden:

The ADC is optimized for analog signals with an output impedance of 
approximately 10 kΩ or less.

von Mahnel (Gast)


Lesenswert?

Fr00sch schrieb:
> am anfang definiere ich
> portB als Ausgang
> ldi r16,0b11111111
> out DDRB,r16

Richtig, damit sind ALLE PBs als Ausgänge geschaltet.

> und gebe allen Pins keinen pullup
> ldi r16, 0x00
> out PORTB,r16

Nicht ganz richtig: damit hast Du ALLE PBs auf "0" geschaltet.
Wenn jetzt eine "Stromquelle" gegen "1" angelegt wird, wird der Strom 
über den MC/Port gegen "0" abfliessen.

...hoffe geholfen zu haben...

von Fr00sch (Gast)


Lesenswert?

Wie müsste der korrekte Code nun aussehen, sodass ich nur den Port 0 als 
ausgang nehme und gegen null schalte... bin etwas verwirrt

@all:danke für die Hilfe bis hierhin

von Peter R. (gelb)


Lesenswert?

Hallo,

statt

  ldi r16, 0b11111111
  out DDRB,r16

verwendest du

  sbi DDRB, 0

um nur einen Portpin als Ausgang zu definieren und

  ldi r16, 0x00
  out PORTB,r16

kannst du weglassen, da das der Ursprungszustand ist.

Grüße, Peter

von Fr00sch (Gast)


Lesenswert?

kA warum, aber deine Idee funktioniert nicht, das Drehen am Poti 
verändert nichts, die helligkeit der LED bleibt konstant bei etwa 50%!

Quellcode jetzt:

1
.include "tn13def.inc"
2
3
4
rjmp   Anfang
5
Anfang:
6
;Pins belegen
7
      sbi    DDRB,0
8
9
;ADC initialisieren
10
      ldi    r16, 0b00100010
11
    out    ADMUX, r16
12
    ldi    r16, 0b11000111
13
    out    ADCSRA, r16
14
15
 
16
Schleife:
17
      sbi    portb,0
18
adc0_wait:
19
    sbic   ADCSRA,ADSC
20
    rjmp   adc0_wait
21
    in     r18, ADCL
22
    in     r17, ADCH
23
    ldi    r16,255
24
    sub    r16,r17
25
Warten1:
26
      dec    r17
27
    brne   Warten1
28
    cbi    portb,0
29
Warten2:
30
      dec    r16
31
    brne   Warten2
32
rjmp Schleife

von Fr00sch (Gast)


Lesenswert?

Hilfe, kann mir denn keiner helfen, habe ich vllt einen grundsätzlichen 
Fehler gemacht?
Verstehe das mit der I/O_ports vllt nicht so richtig.
Wie würdet ihr den ADC ansprechen?
Gruß Fr00sch

von Karl H. (kbuchegg)


Lesenswert?

Wo wird da innerhalb der Schleife der ADC neu gestartet?

Ich hab jetzt auch ehrlich gesagt keine Lust, aus dem Datenblatt
zusammenzusuchen, was du hier

    ldi    r16, 0b11000111
    out    ADCSRA, r16

alles aktiviert hast.

von Fr00sch (Gast)


Lesenswert?

7.)1 macht den ADC an,
6.)start die conversion,
5.)ADC Interrupt Flag keine,
4.)ADC Interrupt Enable aus,
2.)Prescaler Factor
1.)Prescaler Factor
0.)Prescaler Factor

Seite 91 und 92 im Datenblatt

von Fr00sch (Gast)


Lesenswert?

sbic   ADCSRA,ADSC
startet in der schleife die conversion!

von Karl H. (kbuchegg)


Lesenswert?

Fr00sch schrieb:
> sbic   ADCSRA,ADSC
> startet in der schleife die conversion!

Nein.
Das wartet bis die Konvertierung fertig ist.
Aber wo wird sie erneut gestartet?

Dazu müsstest du das ADSC Bit irgendwo erneut setzen. Das tust du aber 
nicht! Mit sbic wird ein Bit abgefragt, aber nicht gesetzt.

  sbic     ... skip (next instruction, if) bit is clear

zusammen mit dem nachfolgendem rjmp ergibt das eine Schleife, die 
solange wartet, bis das ADSC Bit von 1 auf 0 wechselt, welches wiederrum 
laut Beschreibung anzeigt, dass der ADC fertig ist.

von Karl H. (kbuchegg)


Lesenswert?

Fr00sch schrieb:
> 7.)1 macht den ADC an,
> 6.)start die conversion,
> 5.)ADC Interrupt Flag keine,
> 4.)ADC Interrupt Enable aus,
> 2.)Prescaler Factor
> 1.)Prescaler Factor
> 0.)Prescaler Factor
>
> Seite 91 und 92 im Datenblatt

Worauf ich hinaus wollte:
Man kann die Binärzahl auch so schreiben, dass man die Bits beim Namen 
nennt.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC

Vergleich doch mal zb das hier
1
    ldi     temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
2
    out     ADCSRA, temp1
mit deiner Version. Wo sieht man eher, was Sache ist?

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.