Forum: Mikrocontroller und Digitale Elektronik ATtiny13 PWM-Problem


von Felix S. (Firma: CvO Universität) (verfelixt)


Lesenswert?

Hallo,
ich habe folgendes Problem: Es soll ein Analogwert an PB3 eingelesen 
werden (0-5V) und entsprechend ein PWM-Wert an PB0 ausgegeben werden 
(0-255). Ich bin die Register schon im Datenblatt durchgegangen, aber 
kann keinen Fehler finden, PB0 ist dauerhaft auf 5V (Betriebspannung). 
Ich würde mich echt freuen, wenn mir einer von euch sagen kann, wo mein 
Fehler liegt :)

LG
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
  DDRB &= ~(1<<DDB3);
6
  DDRB = (1<<PB0);
7
  
8
  TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00);
9
  TCNT0 = 0;
10
  TCCR0B = (1<<CS01) | (1<<CS00);
11
  
12
  ADMUX = (1<<ADLAR) | (1<<MUX1) | (1<<MUX0);
13
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
14
  
15
  while (1)
16
  {
17
    ADCSRA |= (1<<ADSC);
18
    while (ADCSRA & (1<<ADSC));
19
    OCR0A = ADCH;
20
  }
21
}

von Ingo L. (corrtexx)


Lesenswert?

Felix S. schrieb:
> Ich würde mich echt freuen, wenn mir einer von euch sagen kann, wo mein
> Fehler liegt :)
Der Fehler ist, dass du nicht systematisch vorgehst. Läuft die PWM?
1
  while (1)
2
  {
3
    ADCSRA |= (1<<ADSC);
4
    while (ADCSRA & (1<<ADSC));
5
    OCR0A = ADCH;
6
    OCR0A = 128; // Debug, 50% Duty
7
}
Wenn das schon nicht geht, liegt es erstmal an der PWM

von Felix S. (Firma: CvO Universität) (verfelixt)


Lesenswert?

Nein, das funktioniert nicht.

von Christian F. (neo2001)


Lesenswert?

Mit dem Problem hat es wahrscheinlich nichts zutun, aber anstatt
1
DDRB &= ~(1<<DDB3);
2
DDRB = (1<<PB0);

reicht auch
1
DDRB |= (1<<DDB0);


Die Register stehen per default auf 0 (bzw. siehe Datenblatt). Zudem 
überschreibst du in der zweiten Anweisung sowieso das gesamte Register. 
;-)

von Felix S. (Firma: CvO Universität) (verfelixt)


Lesenswert?

Christian F. schrieb:
> Mit dem Problem hat es wahrscheinlich nichts zutun, aber anstatt
>
>
1
DDRB &= ~(1<<DDB3);
2
> DDRB = (1<<PB0);
>
> reicht auch
>
>
1
DDRB |= (1<<DDB0);
>
>
> Die Register stehen per default auf 0 (bzw. siehe Datenblatt). Zudem
> überschreibst du in der zweiten Anweisung sowieso das gesamte Register.
> ;-)

Das hilft leider nicht, aber danke :)

von Gerhard (Gast)


Lesenswert?

Bist Du sicher, dass Du für den ATtiny13 compilierst?

von Ingo L. (corrtexx)


Lesenswert?

Felix S. schrieb:
> Nein, das funktioniert nicht.
Dann sein kreativ, pack das
1
OCR0A = 128; // Debug, 50% Duty
 vor die while(1)-Schleife

von Holger L. (max5v)


Lesenswert?

Ist der Programmer beim Testen denn abgesteckt, evtl. fängt der sich 
darüber was ein.

Und läuft der ATtinny auf 8 MHz ?

von Felix S. (Firma: CvO Universität) (verfelixt)


Lesenswert?

Ja, ich kompiliere für den ATtiny13...

Ingo L. schrieb:
> Felix S. schrieb:
>> Nein, das funktioniert nicht.
> Dann sein kreativ, pack dasOCR0A = 128; // Debug, 50% Duty vor die
> while(1)-Schleife

Funktioniert auch nicht.

Holger L. schrieb:
> Ist der Programmer beim Testen denn abgesteckt, evtl. fängt der
> sich
> darüber was ein.

Ist mit und ohne das selbe Ergebnis.

> Und läuft der ATtinny auf 8 MHz ?

Nein, auf 9.6 MHz.

: Bearbeitet durch User
von Christian F. (neo2001)


Lesenswert?

Habe mal deinen Code - exakt so wie er im ersten Post ist - auf einen 
neuen ATtiny13A geflasht und dann ein Poti an PB3 und eine LED an PB0 
gesteckt - und er tut genau was er soll - die LED lässt sich mit dem 
Poti dimmen.

Einzige Änderung am µC: Die per Default gesetzte CKDIV8 Fuse entfernt, 
damit er mit vollen 9,6 MHz läuft.

von Felix S. (Firma: CvO Universität) (verfelixt)


Lesenswert?

Christian F. schrieb:
> Habe mal deinen Code - exakt so wie er im ersten Post ist - auf
> einen
> neuen ATtiny13A geflasht und dann ein Poti an PB3 und eine LED an PB0
> gesteckt - und er tut genau was er soll - die LED lässt sich mit dem
> Poti dimmen.
>
> Einzige Änderung am µC: Die per Default gesetzte CKDIV8 Fuse entfernt,
> damit er mit vollen 9,6 MHz läuft.

Auch mit entfernter Fuse läuft es leider nicht. Habe natürlich zu 
Sicherheit alle Verbindungen schon mehrmals überprüft, daran liegt es 
nicht.

von jz23 (Gast)


Lesenswert?

Kommentier mal den Inhalt der while()-Schleife aus (Nicht die Schleife 
selber) und setze OCR0A auf einen festen Wert - 128 bsp. Das sollte 
eigentlich funktionieren, wenn nicht, dann ist wohl der µC hops?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

eigentlich muss das funktionieren.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main(void)
5
{
6
  DDRB = (1<<PB0);
7
  TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00);
8
  TCNT0 = 0;
9
  OCR0A = 0;
10
  TCCR0B = (1<<CS01) | (1<<CS00);  
11
  
12
  while (1)
13
  {
14
    OCR0A = 4;
15
    _delay_ms(2000);
16
    OCR0A = 32;
17
    _delay_ms(2000);
18
    OCR0A = 128;
19
    _delay_ms(2000);
20
    OCR0A = 255;
21
    _delay_ms(2000);
22
  }
23
}

Flashen funktioniert ohne Fehler?
Irgendein Resetproblem?
Spannungsversorgung, Masse ... alles okay?
Wenn flashen klappt muss danach auch die LED was tun ...
Wie misst du am Pin?

von Dieter F. (Gast)


Lesenswert?

Felix S. schrieb:
> Ich würde mich echt freuen, wenn mir einer von euch sagen kann, wo mein
> Fehler liegt :)

Im Aufbau vermutlich ... das Programm schliesse ich auch aus.

von Holger L. (max5v)


Angehängte Dateien:

Lesenswert?

Der Grund für die Frage nach den 8, in diesem Fall natürlich 9,6MHz war 
die Art der Messung. Günstige Multimeter steigen bei zu hohen oder 
niedrigen Frequenzen gerne aus.

Daher:
wie wird die PWM gemessen,
wie wird die Spannung für die Messung erzeugt,
wie ist der Aufbau, Breadboard oder gelötet, saubere Versorgung etc. ?

Das Programm läuft bei mir übrigens auch (zumindest auf einem 
ATtiny13A), um Softwareprobleme auszuschließen ist der Code aus dem 
Eröffnungspost als .hex angehängt.

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.