Но есть минус - теряется таймер. А длительность бипа можно отсчитывать тем же таймером в периодах. Вот пример генерации звука таймером 2:
//------------------------------- Константы: ---------------------------------
#define BeepD 100.0 //длительность стандартного звука, мс
#define BeepF 1.000 //частота стандартного звука, КГц
#define TickD 25.0 //длительность короткого звука, мс
#define TickF 1.500 //частота короткого звука, КГц
//------------------------- Макроопределения: --------------------------------
//Преобразование частоты [KHz] в длительность периода [тики таймера]:
#define KHZ2T(x) (int)((FCLK * 1000.0 / 512.0) / (x))
//Преобразование длительности [mS] в число периодов:
#define MS2P(x, y) (int)((x) * (y) * 2)
//------------------------------- Переменные: --------------------------------
static int SndD; //длительность звукового сигнала в периодах
//--------------- Генерация звука: длительность d, период t: -----------------
void Sound(int d, char t)
{
OCR2 = t;
SndD = d;
TCCR2 = (1<<WGM21) | (1<<COM20) | (1<<CS22); //CTC, toggle OC2, CK/256
TIFR = (1<<OCIE2); //очистка отложенных прерываний
TIMSK |= (1<<OCIE2); //разрешение прерывания таймера 2
}
//----------------- Прерывание таймера для генерации звука: ------------------
#pragma vector = TIMER2_COMP_vect
__interrupt void GenSnd(void)
{
if(!--SndD)
{
TCCR2 = (1<<WGM21) | (1<<COM21) | (1<<CS22); //CTC, clear OC2, CK/256
TIMSK &= ~(1<<OCIE2); //запрещение прерывания таймера 2
}
}
//------------ Генерация стандартного звукового сигнала (beep): --------------
__monitor void Sound_Beep(void)
{
Sound(MS2P(BeepD, BeepF), KHZ2T(BeepF));
}
//------------- Генерация короткого звукового сигнала (teek): ----------------
__monitor void Sound_Tick(void)
{
Sound(MS2P(TickD, TickF), KHZ2T(TickF));
}
//----------------------------------------------------------------------------