Как то так, отставать будет на десяток - другой циклов, считать лень. Частота будет довольно точная, к примеру для кварца 20МГц, и без всяких предделителей 349Гц превратится в 349.0036 Гц, и небольшое запаздывание, в пределах пары микросекунд.
Код для Tiny2313. Частоты могут быть разными, очень разными. В разумных пределах конечно.
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#define INV_B(x) ^=(1<<x)
#define SET_B(x) |= (1<<x)
#define BitIsClear(reg, bit) ((reg & (1<<bit)) == 0)
#define F 20000000
#define f1 550
#define f2 560
#define f3 570
#define f4 580
#define f5 590
#define f6 600
#define n1 (F/(2*f1))
#define n2 (F/(2*f2))
#define n3 (F/(2*f3))
#define n4 (F/(2*f4))
#define n5 (F/(2*f5))
#define n6 (F/(2*f6))
volatile unsigned char overflow;
volatile unsigned int N1,N2,N3,N4,N5,N6;
///////////////////////////////////////////
///////// ISR TIMER0_OVF ////////
///////////////////////////////////////////
ISR (TIMER1_OVF_vect)
{
overflow =0;
if (N1>n1)
{
PORTB INV_B(1);
N1=N1+n1;
}
if (N2>n2)
{
PORTB INV_B(2);
N2=N2+n1;
}
if (N3>n3)
{
PORTB INV_B(3);
N3=N3+n3;
}
if (N4>n4)
{
PORTB INV_B(4);
N4=N4+n4;
}
if (N5>n5)
{
PORTB INV_B(5);
N5=N5+n5;
}
if (N6>n6)
{
PORTB INV_B(6);
N6=N6+n6;
}
}
///////////////////////////////////////////
///////// MAIN ////////
///////////////////////////////////////////
int main(void)
{
overflow = 0;
N1=n1; N2=n2; N3=n3; N4=n4; N5=n5; N6=n6;
TCCR1B = (0<<CS12)|(0<<CS11)|(1<<CS10);
TIMSK = (1<<TOIE1);
sei();
while (1)
{
////// 1 /////
if ((TCNT1>=N1)&(BitIsClear(overflow,1)))
{
PORTB INV_B(1);
N1=N1+n1;
if (N1<n1) overflow SET_B(1);
}
////// 2 /////
if ((TCNT1>=N2)&(BitIsClear(overflow,2)))
{
PORTB INV_B(2);
N2=N2+n2;
if (N2<n2) overflow SET_B(2);
}
////// 3 /////
if ((TCNT1>=N3)&(BitIsClear(overflow,3)))
{
PORTB INV_B(3);
N3=N3+n3;
if (N3<n3) overflow SET_B(3);
}
////// 4 /////
if ((TCNT1>=N4)&(BitIsClear(overflow,4)))
{
PORTB INV_B(4);
N4=N4+n4;
if (N4<n4) overflow SET_B(4);
}
////// 5 /////
if ((TCNT1>=N5)&(BitIsClear(overflow,5)))
{
PORTB INV_B(5);
N5=N5+n5;
if (N5<n5) overflow SET_B(5);
}
////// 6 /////
if ((TCNT1>=N6)&(BitIsClear(overflow,6)))
{
PORTB INV_B(6);
N6=N6+n6;
if (N6<n6) overflow SET_B(6);
}
}
}