ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
30 июня
343795 Топик полностью
Лeoнид Ивaнoвич (30.07.2012 10:42, просмотров: 165) ответил roman183 на Доброго времени суток!
Похожую задачу решает декодер RC-5, ресурсов при этом тратит минимум: //---------------------------------------------------------------------------- //Декодер RC-5 //---------------------------------------------------------------------------- //Декодер использует два прерывания: внешнее от фотоприемника и //прерывание по переполнению таймера 0. //После того, как обнаружен стартовый бит (переход из единицы //в ноль на входе прерывания), в обработчике внешнего прерывания //разрешается прерывание таймера 0 и загружается интервал до первой //выборки T_SAMPLE. В прерывании таймера 0 делаются выборки для //каждной половинки бита. Подсчет выборок ведется в переменной SampCnt. //Количество выборок задается константой SAMPLE_COUNT. //Логический уровень для каждой половинки бита вычисляется по //мажоритарному принципу. Для этого вычисляется сумма выборок //в переменной SampVal. Если на входе обнаруживается ВЫСОКИЙ уровень, //то к этой переменной добавляется единица, если НИЗКИЙ - вычитается. //Значение суммы не может быть равно нулю, так как общее количество //выборок всегда задается нечетным. По первой половине текущего бита //принимается решение о значении принятого бита. Для проверки //корректности кода Манчестер этот уровень сравнивается со значением //второй половины предыдущего бита, которое сохраняется в переменной //PreVal. Если значения совпадают, была ошибка, и прием начинается //с начала. То же самое происходит, если очередной переход на входе //не обнаружен через время T_SAMPLE * 2 после последней выборки //(ошибка таймаута). Принятые биты вдвигаются в переменную Rc5Code. //Подсчет принятых битов осуществляется в переменной BitCounter. //Когда принято RC5_LENGTH битов, прием завершен, номер системы //копируется в переменную SysVar, а код команды - в переменную ComVar. //Декодер поддерживает Extended RC-5 Code, второй стартовый бит //интерпретируется как бит F (Field). Бит F представляет собой //инвертированный дополнительный (старший) бит кода команды, //в результате количество команд удваивается. //---------------------------------------------------------------------------- #include "Main.h" #include "RC5.h" //----------------------------- Константы: ----------------------------------- #define PRE 64 //предделитель таймера 0 #define RC5_SLOT 1778 //длительность слота RC-5, мкс #define RC5_LENGTH 14 //количество принимаемых битов #define SAMPLE_COUNT 3 //количество выборок (должно быть нечетным) #define T_SAMPLE_US (RC5_SLOT / ((SAMPLE_COUNT + 1) * 2)) #define T_SAMPLE (T_SAMPLE_US * F_CLK / PRE + 0.5) //----------------------------- Переменные: ---------------------------------- static char SampCnt; //счетчик выборок static signed char SampVal; //сумма выборок static bool PreVal; //значение предыдущего полуинтервала static int RC5Code; //принятый код static char BitCounter; //счетчик принятых битов static char SysVar; //номер системы static char ComVar; //код команды //-------------------------- Прототипы функций: ------------------------------ #pragma vector = INT0_vect __interrupt void EdgeIR(void); //прерывание по сигналу фотоприемника #pragma vector = TIMER0_OVF_vect __interrupt void TimerIR(void); //прерывание таймера 0 //----------------- Инициализация модуля декодера RC-5: ---------------------- void RC5_Init(void) { BitCounter = RC5_LENGTH; //инициализация счетчика битов PreVal = 1; //перед стартовым битом была единица SysVar = 0xFF; //неиспользуемый код системы ComVar = 0xFF; //неиспользуемый код команды TCCR0 = (1<<CS00) | (1<<CS01); //прескалер CK/64 для таймера 0 MCUCR = (1<<ISC01); //INT0 по спаду GIFR = (1<<INTF0); //очистка отложенных прерываний GICR |= (1<<INT0); //разрешение INT0 } //------------- Обработчик прерывания по сигналу фотоприемника: -------------- #pragma vector = INT0_vect __interrupt void EdgeIR(void) { Port_LED_1; GICR &= ~(1<<INT0); //запрещение INT0 TCNT0 = 256 - T_SAMPLE; //интервал до первой выборки TIFR = (1<<TOV0); //очистка отложенных прерываний TIMSK |= (1<<TOIE0); //разрешение прерываний таймера 0 SampCnt = SAMPLE_COUNT * 2; //общее количесто выборок SampVal = 0; //очистка принятого значения } //------------------ Обработчик прерывания таймера 0: ------------------------ #pragma vector = TIMER0_OVF_vect __interrupt void TimerIR(void) { if(SampCnt) //проверка таймаута { if(Pin_RC5) SampVal++; //если на входе единица, инкремент суммы, else SampVal--; //иначе декремент суммы if(--SampCnt) //декремент количества выборок { if(SampCnt != SAMPLE_COUNT) { TCNT0 = 256 - T_SAMPLE; //продолжаем опрашивать return; } else //первая половина интервала закончилась: { TCNT0 = 256 - T_SAMPLE * 2; //загрузка интервала между сериями выборок bool Val = (SampVal > 0); //оценка бита if(Val != PreVal) //проверка корректности кода Манчестер { RC5Code <<= 1; //сдвиг принятого кода if(!Val) RC5Code |= 1; //первая половина = 0, бит = 1 SampVal = 0; //очистка счетчика выборок return; } } } else //вторая половина интервала закончилась: { TCNT0 = 256 - T_SAMPLE * 2; //загрузка интервала таймаута PreVal = (SampVal > 0); //оценка второй половины бита if(PreVal) //обнаружена единица, MCUCR &= ~(1<<ISC00); //INT0 по спаду, else MCUCR |= (1<<ISC00); //иначе INT0 по фронту GICR |= (1<<INT0); //разрешение INT0 if(--BitCounter) //декремент счетчика битов return; //переход к приему следующего бита SysVar = (RC5Code >> 6) & 0x3F; //номер системы ComVar = RC5Code & 0x3F; //код команды if(!(RC5Code & 0x1000)) //добавление бита F ComVar |= 0x40; } } BitCounter = RC5_LENGTH; //загрузка счетчика битов PreVal = 1; //перед стартовым битом была единица TIMSK &= ~(1<<TOIE0); //запрещение прерываний таймера 0 MCUCR &= ~(1<<ISC00); //INT0 по спаду GICR |= (1<<INT0); //разрешение INT0 Port_LED_0; } //------------------------- Чтение номера системы: --------------------------- char RC5_GetSys(void) { return(SysVar); } //-------------------------- Чтение кода команды: ---------------------------- char RC5_GetCom(void) { return(ComVar); } //----------------------------------------------------------------------------