Forum: Compiler & IDEs ATTiny45 PWM Counter 1


von Mehmet K. (mkmk)


Lesenswert?

Servus allerseits

ATTiny45 mit internem 1Mhz Oszilator.
Zuerst habe ich die Testschaltung mit Timer0 aufgebaut, da ich dazu 
funktionierende Sourcen hatte. Hat auch wunderbar funktioniert.
Da aber 1MHz nicht gerade dazu geeignet ist, um damit vernünftlich PWM 
zu backen, habe ich den Transistor von Port B0 auf B4 umgelötet und die 
Software auf Timer1 mit PLL umgeschrieben. Das war heute morgen. Jetzt, 
nach 8 Stunden bin ich keinen Schritt weiter.

1
void Timer_1_init( void )
2
{ 
3
 //===========
4
  PLLCSR = ( 1<<  PLLE);               // enable PLL
5
  while(BIT_IS_CLEAR(PLLCSR, PLOCK));  // warten bis PLL locked
6
  PLLCSR |= ( 1<<  PCKE);              // after PLL is locked, use 64MHz as clock source for Timer1
7
  //============
8
9
  GTCCR  = ( 1 << PWM1B);     // enable PWM 
10
  GTCCR |=( 1 << COM1B1) | ( 0 << COM1B0); // OC1B cleared on compare match
11
12
  TCCR1  |= ( 1<< CS13) | (1 << CS12)  | (0 << CS11) | (0 << CS10);      // presc. 64 MHz / 2048
13
14
  OCR1C  = 0xFF;   //  max value
15
  OCR1B  = 0x00;   // compare value
16
17
  TIMSK  |= ( 1 << OCIE1B);  // compare match interrupt
18
}

Die Interrrupt Routine:
1
ISR(TIMER1_COMPB_vect)
2
{ 
3
  OCR1B = adc_value;   // change compare value
4
  BIT_SET(ADCSRA, ADSC); // start a new ADC conversation
5
}

Bevor ich Timer_1_init() aufrufe, kann ich die LED mit SWITCH_ON und 
SWITCH_OFF ein- und ausschalten. Nach dem Init bleibt die LED konstant 
ON. Oder, wenn ich COM1B0 und COM1B1 aendere, konstant OFF.
Wenn ich OCR1C verkleinere, wird die Interrupt Rountine dementsprechend 
schneller aufgerufen. Das Gerüst scheint also i.O. zu sein.

Waere dankbar, wenn mit jemand einen Tip geben könnte.

Mfg

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hast du eine Chance, da mal mit debugWIRE reinzugucken?

von Mehmet K. (mkmk)


Lesenswert?

Servus Jörg

Ich habe das Ganze so gelöst, dass ich anstelle von OC1B nun OC1A 
benutze. Und damit klappts. Mit OC1B hatte ich dermassen absurde 
Probleme, dass ich mich gar nicht getraue, sie hier alle aufzuzaehlen. 
:)
Der obige Code ist aber an sich i.O.

Der einzige Ueberlegungs-Fehler im Code ist nur der, dass wenn man den 
Compare-Interrupt mit 64Mhz-Clock aktiviert, dass dieser Interrupt alles 
andere überfaehrt. So im nachhinein in Ruhe nachgedacht, neige ich dazu, 
diesen Fehler als die eigentliche Quelle meines Problems zu sehen. Aber 
sicher bin ich mir nicht.

Danke für die Anteilnahme.

von Mehmet K. (mkmk)


Lesenswert?

Vollstaendigkeitshalber der Code, so wie er z.Zt. bei mir einwandfrei 
laeuft:
1
void Timer_1_init( void )
2
{ 
3
4
 // PLL einschalten
5
 PLLCSR = ( 1<<  PLLE);               // enable PLL
6
 while(BIT_IS_CLEAR(PLLCSR, PLOCK));  // warten bis PLL locked
7
 PLLCSR |= ( 1<<  PCKE);              // after PLL is locked, use 64MHz as clock source for Timer1
8
 
9
  
10
  // PWM OC1A
11
 TCCR1  = ( 1<< PWM1A) | ( 1 << COM1A1) | ( 0 << COM1A0);
12
  
13
//   TCCR1  |= ( 0<< CS13) | (0 << CS12)  | (0<< CS11) | (1 << CS10);      // presc. 64 MHz / (1 * 256) -> 250kHz
14
  TCCR1  |= ( 0<< CS13) | (0 << CS12)  | (1<< CS11) | (0 << CS10);      // presc. 64 MHz / (2 * 256) -> 125kHz
15
  //TCCR1  |= ( 0<< CS13) | (0 << CS12)  | (1<< CS11) | (1 << CS10);      // presc. 64 MHz / (4 * 256) -> 62.5kHz
16
 //TCCR1  |= ( 0<< CS13) | (1 << CS12)  | (0<< CS11) | (0 << CS10);      // presc. 64 MHz / (8 * 256) -> 31.25kHz
17
18
//  TIMSK  |= ( 1 << OCIE1A);  // compare match interrupt. Achtung! Wenn enabled, kann je nach Vorteiler kein anderer Interrupt mehr zum Zuge kommen
19
20
  OCR1C = 0xFF;
21
  OCR1A = 0xFF; 
22
}

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.