Почитав темы на этом форуме, написал код, который отслеживает изменение входного уровня с ИК приемника и, в зависимости от пересылаемого, обрабатывает данные. прерывание только одно- по переполнению таймера0. пульт Сони, вроде все ясно, код писал давно: еще в сентябре, недавно решил протестировать, но почему-то не срабатывает прерывание. еще раз перепроверил текст. если кому-то нетрудно, проверьте и вы, а то последний шанс для допуска к экзаменам:
одно переполнение должно происходить за 0,5-0,55мс, несущая 40кГц как-то это влияет? light-версия:
unsigned char sirc_t =0; //Счетчик длины импульсов в тиках таймера unsigned char sirc_cnt=0; //К-во принятых бит unsigned int sirc_data=0; //хранилище принимаемых данных unsigned char rs_bit_temp=0; //хранит состояние входа unsigned char rs_bit_temp1=0; //тоже хранит. для сравнения.
//Обработчик прерывания таймера. Подсчитываем длинну импульса в T.
#pragma vector=TIMER0_OVF_vect __interrupt void irqHandler(void) { TCNT0=135; // Перегрузка таймера sirc_t++; // Это счетчик длины импульса }//TIM0_OVF
void main() { DDRB=0xFB; //Рег напр PORTB: 1111 1011.все кроме PB2 на вывод, PB2-вход с ИК SREG|=(1<<7); //разрешить прерывания
while(1) { _WDR(); rs_bit_temp=(PINB&(1<<PB2))>>PB2; //взяли значение в PB2: сканируем изменение состояние с ИК приемника rs_bit_temp1=rs_bit_temp; __delay_cycles(0.00001*CPU_FREQ);//5-10мкс rs_bit_temp=(PINB&(1<<PB2))>>PB2; //еще раз взяли if(rs_bit_temp==rs_bit_temp1) {} //изменения на входе не было, ск else { //уровень изменялся if((rs_bit_temp1==0)&&(rs_bit_temp==1))/*(0->1)обработка прин. бита (т.к.сигнал в инверсии, то фронт 1-0 это окончиние
импульса, которое сигнализирует о начале процедуры обработки). */ { TCCR0=0x00 //Выключение таймера timer0. смотрим сколько раз натикало. if(sirc_cnt>0){ //Если принимаем основное тело посылки sirc_data = sirc_data >> 1;//сдвигаем биты хранилища sirc_addr = sirc_addr | ((sirc_t == 2)<<4);//и ставим принятый бит
sirc_cnt++; //К-во принятых бит +1 } //Анализируем длинну посылки... if (sirc_t==4){ //Стартовый бит (4T)... sirc_addr=0x00; //...инициализация переменных,... // ...готовимся к приему данных sirc_cmd =0x00; sirc_cnt =1; //счетчик выставляем. } //end 4T Конец инициализации else{ //Проверяем на ошибку if ((sirc_t != 2) && (sirc_t != 1)) //Не 4 и не 2 и не 1 ... sirc_cnt=0; // значит ОШИБКА! } //... конец анализа длинны посылки. if (sirc_cnt==13){ //ПАКЕТ ПРИНЯТ!!! sirc_cmd = sirc_cmd >> 1; // сдвигаем данные команды //что-то делаем _WDR(); sirc_cnt=0; } //if (sirc_cnt==13) } //if((rs_bit_temp1==0)&&(rs_bit_temp==1))//(0->1)обработка прин. else{ //(1->0)Начинается импульс TCNT0=135; //Перезагрузка таймера.(t = 0,52245 мс) f=7,350 000 MegHz f/32, прескалер 255-(120)= //т.е. отсчитывает всего 120 TCCR0=0x03; //Включение таймера. timer0 f/32 b0000 0011 SREG|=(1<<7); //разрешить прерывания } sirc_t=0; //СЧЕТЧИК тиков СБРОСИТЬ } //закончилось else от if(rs_bit_temp==rs_bit_temp1) _WDR();
} // от while(1) } // main }
|