Добро пожаловать!


Моя реализация приемника RC5.

На рисунке сверху - структура посылки передатчика.
Внизу, то что на входе приемника (например с выхода SFH-506).


По первым двум стартовым битам вычисляется период Р. Затем, как видно из рисунка, через время равное Р находится середина следующего бита и смена уровней, которое определяет значение бита. Падающий фронт - бит равен единице, нарастающий фронт - бит равен нулю.
При приходе первого стартового бита взводится флаг сброса приемника и его активное время Р*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; работать не захотела (меняет байты местами).
Реально программа проверялась через HyperTerminal.
скачать (21 Kb).

На главную - startcd.narod.ru



Hosted by uCoz