Добро пожаловать! Моя реализация приемника RC5.
На рисунке сверху - структура посылки передатчика. По первым двум стартовым битам вычисляется период Р. Затем, как видно из рисунка, через время равное Р находится середина следующего бита и смена уровней, которое определяет значение бита. Падающий фронт - бит равен единице, нарастающий фронт - бит равен нулю. При приходе первого стартового бита взводится флаг сброса приемника и его активное время Р*17, если за это время команда не принята, то устанавливается флаг ошибки, приемник инициализируется на новый прием. В программе используются два прерывания, по захвату состояния таймера (основное) и по совпадению (сброс приемника).
ISR(TIMER1_CAPT_vect){//прерывание по захвату состояния таймера static uint16_t period, receive; static uint8_t counter_bit; uint16_t capture; //capture=ICR1;// в протеусе 7,2 не работает capture=TCNT1; if ( rc5.flag & FL_SAMPLE ){ // середина бита (пропускаем значение capture меньше периода) if ( (capture > period-TOLERANCE)&&(capture < period+TOLERANCE) ) { TCNT1=0; receive<<=1; // если прер. было по падающему фронту то бит==1 if ( (TCCR1B & _BV(ICES1))==0 ) receive|=1; if (++counter_bit==12) { rc5.data=receive; rc5.data_ok=1; rc5.flag &= ~FL_FAULT; } } TCCR1B ^= _BV(ICES1); } else if ( (rc5.flag & FL_STBIT_1)==0 ){//инициализация приема OCR1A=FAULT_TIME_RC5; TCNT1=0; rc5.flag = FL_STBIT_1|FL_RC5_RESET; } else if ( rc5.flag & FL_STBIT_1 ){// измерение периода period=capture; if (( period > RC5_T-TOLERANCE )&&( period < RC5_T+TOLERANCE )) { TCNT1=0; rc5.flag = FL_SAMPLE|FL_RC5_RESET|FL_FAULT; receive=counter_bit=0; TCCR1B |= _BV(ICES1); } } } ISR (TIMER1_COMPA_vect){//прерывание по совпадению if ( rc5.flag & FL_RC5_RESET ){ if ( rc5.flag & FL_FAULT ) rc5.error=1; rc5.flag = 0; TCCR1B &= ~_BV(ICES1); } }
В примере для протеуса, для имуляции передатчика была написана
простенькая программа на atmega16. Почему то в протеусе эта строчка
capture=ICR1; работать не захотела (меняет байты местами). |