Собрал контроллер и передатчик ИК и написал программы.
Идея такая, чтоб через самосборный джойстик передавать команды на контроллер.
Принцип работы ИК передатчика такой:
1) нажимаем кнопку
2) на контроллер приёмника пускается импульс определённой длительности
Вот код который генерирует импульсы по прерыванию:
Код
// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
if(empty) PORTB.0++;//генерация несущей 30кГц
else PORTB.0 = 0;
timen1++;
timen2++;
//Вычисление длинны импульса
if(pulse)
{
empty = 1;
pulse--;
}
if(!pulse) { empty = 0;}
}
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
if(empty) PORTB.0++;//генерация несущей 30кГц
else PORTB.0 = 0;
timen1++;
timen2++;
//Вычисление длинны импульса
if(pulse)
{
empty = 1;
pulse--;
}
if(!pulse) { empty = 0;}
}
Пакетный режим пока не выходит организовать, т.к. что то сбоит.
Удалось только подавать пакет вида /старт бит/бит данных/стоп бит/.
МК передатчика генерирует прерывание с частотой 60кГц.
И если нужно передать импульс, то на выход поступает сигнал.
Например лог 0 означает, подать импульс длительностью 20 прерываний.
Лог 1, импульс длительностью 90 прерываний.
Пауза между импульсами 100 прерываний.
Если не передавать пакеты, то приёмник довольно хорошо принимает импульсы и загорается нужный светодиод, но таким макаром мне удалось закодировать только 3 команды.
Если передавать пакетом всё накрывается

У приёмника похожая логика.
Ножка сигнальная TSOP1730 подключена к выводу МК и генерирует прерывание.
Код
// Pin change 0-7 interrupt service routine
interrupt [PCINT0] void pin_change_isr0(void)
{
if(PINB.1 == 0)
{empty = 1;}
else
{empty = 0;}
}
interrupt [PCINT0] void pin_change_isr0(void)
{
if(PINB.1 == 0)
{empty = 1;}
else
{empty = 0;}
}
А прерывание по таймеру происходит с частотой 60кГц и меряет длительность импульса:
Код
// Timer 2 output compare interrupt service routine
interrupt [TIM2_COMPA] void timer2_compa_isr(void)
{
timen++;
timeoff++;
timecomand++;
if(empty) timecount++;//отчёт длинны импульсов
if(timecount && !empty)
{
if(timecount > 7 && timecount < 40) pulse = 1;//лог 0
if(timecount > 50 && timecount < 100) pulse = 2;//лог 1
// if(timecount > 120 && timecount < 230) pulse = 3;//доп. команда
// if(timecount > 250 && timecount < 550) pulse = 4;//доп. команда
timecount = 0;
}
}
interrupt [TIM2_COMPA] void timer2_compa_isr(void)
{
timen++;
timeoff++;
timecomand++;
if(empty) timecount++;//отчёт длинны импульсов
if(timecount && !empty)
{
if(timecount > 7 && timecount < 40) pulse = 1;//лог 0
if(timecount > 50 && timecount < 100) pulse = 2;//лог 1
// if(timecount > 120 && timecount < 230) pulse = 3;//доп. команда
// if(timecount > 250 && timecount < 550) pulse = 4;//доп. команда
timecount = 0;
}
}
А в цикле функции main уже идёт обработка данных, как у приёмника так и у передатчика.
Ниже подшиваю фотки платы, схемы и исходников на СИ в CodeVisionAVR с комментариями.
Очень хотелось бы понять, где закралась ошибочка ?
----------------------------------------------
Есть ещё интересный глюк, если передатчик включить и положить рядом с приёмником, то приёмник ловит иногда команды, но если передатчик выключить, то приёмник ничего не ловит.