Работу слейва,как вариант, можно описать следующим образом. Будем считать пакет принятым, если после приема последнего байта пакета истекла пауза равная времени передачи трех байтов, в течение которой не было принято ни одного байта. Если же во время паузы принимаем байт, то считаем его последним и вновь отслеживаем истечение паузы. И так далее пока пауза не истечет и пакет не будет принят. Отслеживанием паузы занимается таймер, в прерывании которого просто устанавливаем какой-либо флаг. К примеру:
//-------------------------------------------------------------------------------------------
unsigned char Read_USART(unsigned char kol) // kol - число байт, которое хотим принять
{
unsigned char i;
for(i=0;i<kol;i++)
{
TimerFlag0=0; //очищаем флаг срабатывания таймера
TCNT0=0xC8; //значение, соответсвующее паузе ~1.75мс
TCCR0=0x04; //запускаем таймер
//ожидаем приема байта
while (!(UCSRA & (1<<RXC)))
{
if(TimerFlag0) //проверка, время ожидания истекло
{
//возвращаем число реально принятых байт
return i;
}
//сбрасываем сторожевой таймер
WDR();
}
//считываем байт
buf[i]=UDR;
TCCR0=0x00;
}
return i;
}
//---------------------------------------------------------------------------------------
//Прерывание от таймера 0, свидетельствует о превышении интервала ожидания для приема байта
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{ TCCR0=0x00; //останавливаем таймер
TimerFlag0=1; //устанавливаем флаг срабатывания
}
В основной программе:
//принимаем пакет
k=Read_USART(IN_BUF_LEN);
//анализируем его
error = AnalizeBuf(k);