PWM的周期由定时器的溢出率决定。在“操作模式”部分需要考虑很多设置。如果您要做的只是生成具有可变占空比的恒定周期方波,我想您将要使用CTC(比较匹配时清除计时器)模式。基本思想是将OCR0A设置为计时器的滴答数,直到您希望引脚下次切换为止,然后使用“比较匹配”中断在下一次更改该值。因此在avr-gcc中,它看起来像:
#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;
}
}
警告,这是未经测试的代码,但我认为这个想法是正确的。这绝不是唯一的方法。
顺便说一句,您应该了解ATTiny13一件事。内部RC振荡器仅保证在出厂时的精度在10%以内。您可以执行一个用户校准过程(由atmel 应用笔记进行描述),以使ATTiny13的准确度提高2%。如果您想做得更好,则可能需要使用可容纳外部晶体的芯片...