//Библиотека функций RC-5 (rc5.c), РадиоХобби, №4/2006  =1
#include <avr/io.h>           //Библиотека ввода-вывода =2
#include <avr/interrupt.h>      //Библиотека прерываний =3
#define RC5 PD2    //Условное имя для входа подачи RC-5 =4
#define RC5addr 0x00           //Код адреса пульта RC-5 =5
#define WAIT { while(tm==0); tm=0; count++;	} //Сокращ. =6
volatile unsigned char tm=0;       //Флаг для таймера-0 =7
volatile unsigned char clock=0xA0; //Длительность такта =8
//---------Внутреннее прерывание по таймеру-0---------- =9
ISR(SIG_OVERFLOW0)         //По переполнению таймера-0 =10
{ tm=1;         //Установка флага срабатывания таймера =11
  TCNT0=clock; //Начальное значение таймера-0 (111 мкс)=12
}      //Окончание обработчика прерывания по таймеру-0 =13
//---------Функция декодирования кода RC-5------------ =14
unsigned char rc5decoder(void) //Вых.параметр -команда =15
{ unsigned char count,h,j;  //Вспомогательные счетчики =16
  unsigned int data=0x0001;   //Пакет данных из 14 бит =17
  TCCR0=0x01;	TIMSK |= _BV(TOIE0);  //Режимы таймера-0 =18
		TCNT0=clock; sei();        //Инициализация таймера-0 =19
		tm=0; count=0;                 //Обнуление счетчиков =20
		while((bit_is_clear(PIND, RC5))&&(count<11)) WAIT; //=21
		if ((count > 6)&&(count < 11))     //Проверка фронта =22
  { while (count < 14) WAIT; //Переход к следующ. биту =23
				for (h=0; h<13; h++)     //Цикл обработки 13 битов =24
				{	data = data << 1;    //Сдвиг влево пакета данных =25
				  if (bit_is_set(PIND, RC5))  //Если бит равен "1" =26
						{ data |= 0x0001; //Установка в "1" младш.разряда=27
						  count=0;                  //Обнуление счетчика =28
						  while((bit_is_set(PIND, RC5))&&(count<16)) WAIT;		
						}      //Переход к следующему биту пакета данных =30
						else                        //Если бит равен "0" =31
						{ data &= 0xFFFE; //Установка в "0" младш.разряда=32
						  count=0;                  //Обнуление счетчика =33
						  while((bit_is_clear(PIND, RC5))&&(count<16)) WAIT;
						}      //Переход к следующему биту пакета данных =35
						if (count == 16) //Если слишком длинное ожидание =36
						{ data = 0; break;    //Досрочный выход из цикла =37
						}            //при сбое информации в пакете RC-5 =38
						for (j=0; j < 12; j++) WAIT;          //Ожидание =39
		  }      //Окончание сбора информации в пакет данных =40
    if(((data >>6) & 0x1F) != RC5addr) data=0; //Ошибка=41
	 }            //Окончание сбора и проверки информации =42
  TIMSK &= ~(_BV(TOIE0));	//Запрет прерываний таймера-0=43
		return (data & 0x3F); //Выход с кодом команды 0...63 =44
}                     //Окончание функции "rc5deсoder" =45
