Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: прерывание по переполнения timer0
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
MKV
Почитав темы на этом форуме, написал код, который отслеживает изменение входного уровня с ИК приемника и, в зависимости от пересылаемого, обрабатывает данные. прерывание только одно- по переполнению таймера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
}
AlexG_changed
Не хватает разрешения прерывания по переполнению таймера0.

PS: Для работы с соневским пультом все уже написано. Сайта, где я брал когда-то исходники, больше нет, но обнаружилась перепечатка(?) здесь:
http://www.sibaudio.ru/?id=30&pid=34&cid=1
http://www.sibaudio.ru/?id=30&pid=34&cid=2
MKV
значит нужно в последнем else :
Цитата
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); //разрешить прерывания
}

вставить
TIMSK |= (1<<TOIE0);
вместо
Цитата
SREG|=(1<<7); //разрешить прерывания


есть еще что-то потенциально неработоспособное?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.