Tiny45 und PWM

OP #1405316
Lesenswert?

Hallo,
ich versuche mit TC 0 eine PWM an Ausgang PB1 zu erzeugen.
Im Simulator als auch in der Testschaltung, passiert an PB 1 gar nichts.
Kann mir jemand sagen, was noch konfiguriert werden muss?
das programm habe ich erst mal abgekürzt.
Für die 3 Ints sind routinen vorhanden.

Wäre nett, wenn sich das jemand anschauen könnte.

Vielen Dank!
1
MCUCR|=(1<<PUD);
2
  DDRB=(1<<PB1); //Ausgang PWM
3
  
4
  TCCR0A=((1<<WGM00)|(1<<WGM01)|(1<<COM0B0));
5
  
6
  TCCR0B=((1<<CS01)); //Vorteiler 8
7
  OCR0A=127;  //50 %output für Start
8
  OCR0B=127;
9
  
10
  
11
  TIMSK|=((1<<OCF0A)|(1<<OCF0B)|(1<<TOV0)); //Int ein
12
  TIFR|=((1<<OCF0A)|(1<<OCF0B)|(1<<TOV0));
13
  sei();

  while(1);
#1405496
Lesenswert?

Dir ist klar, dass:
 - es min. 1000 Takte(127*8) dauert, bis da was passiert? (Falls du's 
nur im "Single Step mode" probiert hast)
 - "toggle on compare match" (nicht an- oder aus- sondern um- 
schalten, bei erreichen des OC0X-Werts) für PWM relativ ungünstig ist? - 
wahrscheinlich willst du "Clear on compare match".
 - die Bits im Register "TIMSK" nicht so heißen wie in deinem Code, 
sondern "OCIE0A", "OCIE0B", "TOIE0" (Das sollte aber bei diesem AVR 
nichts ausmachen, deine falschen Namen sind an der richtigen Stelle) ?
 - du auch die passenden ISRs brauchst, wenn du die Interrupts 
aktivierst (Die PWM funktioniert auch ohne die Interrupts)?
 - du 'PB0' nicht auf Ausgang geschaltet hast (der Ausgang für OC0A)?
 - du ALLE Pull-ups abgeschaltet hast?
 - du das TIFR-Register gar nicht anfassen musst, wenn du den Prescaler 
(TCCR0B) erst am Ende der Initialisierung (direkt vor dem 'sei()') 
setzt?

Und was heißt "in der Testschaltung passiert an PB1 gar nichts"? Wie 
stellst du das fest?

hth, Jörg
OP #1405544
Lesenswert?

Hallo Jörg,

 - es min. 1000 Takte(127*8) dauert, bis da was passiert? (Falls du's
nur im "Single Step mode" probiert hast)

<< Auto step und habe schon gewartet, bis der counter ein paar mal 
hochgezählt hat.


 - "toggle on compare match" (nicht an- oder aus- sondern um-
schalten, bei erreichen des OC0X-Werts) für PWM relativ ungünstig ist? -
wahrscheinlich willst du "Clear on compare match".
<< Ich habe den Fast PWM Mode gesetzt.
Soweit ich es verstanden habe, wird der Ausgang bei erreichen gesetzt 
und am Überlauf (Bottom) rückgesetzt



 - du auch die passenden ISRs brauchst, wenn du die Interrupts
aktivierst (Die PWM funktioniert auch ohne die Interrupts)?

<< wie oben geschrieben, sind diese vorhanden und werden auch 
aufgerufen.

 - du 'PB0' nicht auf Ausgang geschaltet hast (der Ausgang für OC0A)?

<< ich verwende OC0B, daher PB1

 - du ALLE Pull-ups abgeschaltet hast?

<< ja war ein versuch

 - du das TIFR-Register gar nicht anfassen musst, wenn du den Prescaler
(TCCR0B) erst am Ende der Initialisierung (direkt vor dem 'sei()')
setzt?

<< wusste ich nicht

Und was heißt "in der Testschaltung passiert an PB1 gar nichts"? Wie
stellst du das fest?

<<Oszi
,
Grüße Michael
#1405605
Lesenswert?

>> - "toggle on compare match" (nicht an- oder aus- sondern um-
>> schalten, bei erreichen des OC0X-Werts) für PWM relativ ungünstig ist? -
>> wahrscheinlich willst du "Clear on compare match".
> Ich habe den Fast PWM Mode gesetzt.
Da haben wir beide nicht richtig gelesen ;)
Aber nur COM0X0=1 ist in dem Datenblatt, das ich gerade anschaue, bei 
"Fast-PWM-mode" 'reserved'.
Probier mal:
1
  TCCR0A=((1<<WGM00)|(1<<WGM01)|(1<<COM0B1));
2
  //  Clear on OC0B on compare match     ^
> Ich verwende OC0B
Warum richtest du dann OC0A ein?

hth, Jörg
OP #1405670
Lesenswert?

Hallo

die Initialisierung sieht nun so aus (nach deinen Anregungen)
1
DDRB=(1<<PB1|1<<PB4|1<<PB0); //Ausgang PWM
2
  
3
  TCCR0A=((1<<WGM00)|(1<<WGM01)||(1<<COM0B1)|(1<<COM0B0));
4
  
5
  TCCR0B=((1<<CS01)); //Vorteiler 8
6
  OCR0A=127;  //50 %output für Start
7
  OCR0B=127;
8
  
9
  
10
  TIMSK|=((1<<OCIE0A)|(1<<OCIE0B)|(1<<TOIE0)); //Int ein
11
  
12
  sei();
Nur (1<<OCIE0B) habe ich auch getestet.
Ich verwende den Timer doppelt, daher auch die Interrupts, die aber 
nicht stören dürften.
Testweise habe ich sie ebend deaktiviert.- Keine Änderung.

Michael
#1405755
Lesenswert?

Dann bin ich auch ratlos, also die Routinefragen :
Funktioniert die Schaltung sicher (d.h. du kannst den Pin dauerhaft 
ein/ausschalten, mit Warteschleife togglen, im Interrupt togglen) ?
Kannst du das ganze Programm posten ?
Hast du irgendwelche Compilerwarnungen? (evtl. brauchst du noch "-Wall" 
"-Wextra", falls da was kommt)
Flashst du die richtige Datei ;) ? (Meistens sind's ja doch die 
blödesten Fehler).
Ist der Programmer bei den Tests angeschlossen(bzw. könnte der stören)?

hth, Jörg
Gast #1405785
Lesenswert?

Mach mal aus Deinem Code hier:

>> DDRB=(1<<PB1|1<<PB4|1<<PB0); //Ausgang PWM

>>   TCCR0A=((1<<WGM00)|(1<<WGM01)||(1<<COM0B1)|(1<<COM0B0));

das hier:
1
DDRB=((1<<PB1)|(1<<PB4)|(1<<PB0)); //Ausgang PWM
2
  
3
  TCCR0A=((1<<WGM00)|(1<<WGM01)|(1<<COM0B1)|(1<<COM0B0));

Die Klammern erfüllen schon einen gewissen Sinn ;-) Bei der zweiten 
Zeile ist ein || drin, das ist etwas Anderes als ein |
Schalte die Interrupts zum Testen ab.

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