Tiny45 und PWM

OP #1405316
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
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
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
>> - "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
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
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
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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.