Die Dauer der PWM wird durch die Überlaufrate Ihres Timers bestimmt. Im Abschnitt Betriebsmodi gibt es viele Einstellungen, über die Sie nachdenken müssen. Wenn Sie lediglich eine Rechteckwelle mit konstanter Periode und variablem Arbeitszyklus erzeugen möchten, sollten Sie den CTC-Modus (Clear Timer on Compare Match) verwenden. Die Grundidee besteht darin, OCR0A auf die Anzahl der Timer-Ticks einzustellen, bis der Pin als nächstes umgeschaltet werden soll, und den Interrupt "Vergleich vergleichen" zu verwenden, um diesen Wert für das nächste Mal zu ändern. In avr-gcc würde es also ungefähr so aussehen:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
// global variables defining number of ticks on and off
uint8_t on_time_ticks, off_time_ticks, csxx_bits=0;
void setup_timer(double p_ms, double duty){
TCCR0A = _BV(COM0A0) // toggle OC0A on Compare Match
TCCR0B = _BV(WGM02); // set CTC mode WGM0[2,1,0] = 0b100
// ... do some stuff based on your CPU frequency
// to define the csxx_bits of TCCR0B when the timer is running
// and consequently, to set on_time_ticks and off_time_ticks
OCR0A = on_time_ticks;
TCCR0B |= your_settings_here;
}
void start_timer(){
//start the timer running at the desired rate
TCCR0B |= csxx_bits;
}
int main(int argc, char **argv){
double period_ms, duty_cycle;
setup_timer(period_ms, duty cycle);
start_timer();
for(;;){
//spin or sleep or whatever
}
}
ISR(TIM0_COMPA_vect){
if(OCR0A == on_time_ticks){
OCR0A = off_time_ticks;
}
else{
OCR0A = on_time_ticks;
}
}
Achtung, dies ist ungetesteter Code, aber ich denke, die Idee ist richtig. Dies ist keineswegs der einzige Weg, dies zu tun.
Es gibt übrigens eine Sache, die Sie über den ATTiny13 wissen sollten. Es wird garantiert, dass der interne RC-Oszillator nur bis zu 10% von der Fabrik entfernt ist. Es gibt einen Benutzerkalibrierungsprozess, den Sie durchlaufen können (beschrieben durch eine atmel- Appnote ), der Sie auf eine Genauigkeit von 2% für den ATTiny13 bringt. Wenn Sie es besser machen wollen, müssen Sie wahrscheinlich einen Chip verwenden, der einen externen Kristall aufnehmen kann ...