#include #include #include #include #include //*************************************************************************************************************************** //БИБЛИОТЕКА ОБРАБОТКИ СИГНАЛА ИК ПУЛЬТА ДИСТАНЦИОННОГО УПРАВЛЕНИЯ СТАНДАРТА NEC //для частоты ATMEGA168P контроллера 8000000 Hz //при работе IR NEC задействован таймер\счетчик T0. //выход IR сенсора подать на внешнее прерывание INT1 //программа создана SHADS //НАСТРОЙКА ПОРТА И ВЫВОДА IR СЕНСОРА #define IR_NEC_PORT PORTD #define IR_NEC_DDR DDRD #define IR_NEC_Line (1<<3) //*************************************************************************************************************************** //переменные и флаги библиотеки char IrNecData [4]; //массив байтов для приема данных char IrNecCounBites; //счетчик принятых битов данных volatile char IrNecFlags; //байт флагов #define bIrNecStreamEnb (1<<0) /*флаг наличия запущеннного процесса приема серии*/ #define bIrNecRcvCmpltd (1<<1) /*флаг завершения приема данных*/ #define bIrNecTmrOvf (1<<2) /*флаг фиксации переполнения счетчика\таймера*/ //*************************************************************************************************************************** //инициализация работы библиотеки void IrNecInit (void) { //настройка порта IR_NEC_DDR &= ~IR_NEC_Line; //линия на ввод IR_NEC_PORT |= IR_NEC_Line; //включить подтяжку DDRC = 0b11111111; PORTC = 0b00000000; //Настройка таймера/счетчика T0 TCCR0B = 0x05; //настройка тактирования T0 (0x01-clk, 0x02-clk/8, 0x03-clk/64, 0x04-clk/256, 0x05-clk/1024) TIMSK0 |= (1< 70) && (val < 140)){ //105 - длительность периода импульса старта (берем шире 70 - 140) IrNecCounBites = 0; //обнулить счетчик принятых битов flags |= bIrNecStreamEnb; //установить флаг приема IrNecFlags = flags; return; } //если прием активен (т.е. заголовок пакета уже был) if (flags & bIrNecStreamEnb){ //проверка на правильность длины импульса if ((val < 6) || (val >= 24)){ //ошибочный размер периода flags &= ~bIrNecStreamEnb; //сбросить флаг приема (т.е. начать с начала) IrNecFlags = flags; return; } //вычисляем место в буфере, куда поместим принятый бит char* pIrNecData = IrNecData + (IrNecCounBites >> 3); char BitNum = 0x80 >> (IrNecCounBites & 0x07); if (val >= 12) *pIrNecData |= BitNum; //принятый бит = 1 (бит = 1 если значение 12-23) else *pIrNecData &= ~BitNum; //принятый бит = 0 (бит = 0 если значение 6-11) //проверка, принята ли вся серия IR NEC if (++IrNecCounBites == 32){ //приняты все 32 бита if ((char)~IrNecData[0] == IrNecData[1]){ //сравниваем прямую и инверсную части адреса устройства if ((char)~IrNecData[2] == IrNecData[3]) //сравниваем прямую и инверсную части команды //данные верны - установить флаг наличия готовых данных flags |= bIrNecRcvCmpltd; } flags &= ~bIrNecStreamEnb; //сбросить флаг приема (т.е. начать с начала) IrNecFlags = flags; } } } //*************************************************************************************************************************** //Прерывание по переполнению T0 ISR (TIMER0_OVF_vect) { IrNecFlags |= bIrNecTmrOvf; //флаг переполнения } int main() { IrNecInit (); while (1) if (IrNecDataCheck()) { PORTC = IrNecDevNumGet(); _delay_ms(500); PORTC = IrNecCommandGet(); _delay_ms(500); } return 0; }