Для реализации достаточно иметь одну свободную ножку порта, желательно с функцией PWM (в нашем случае PD5). И ИК светодиод с длинной волны 800 - 950 нм. Светодиод я подключил через ключевой n-p-n транзистор для усиления мощности импульса. Т.е. светодиод горит, если на ножке 1. Если подключать напрямую без транзистора, то будет наоборот. Картинки здесь.
Для начала, надо определиться с ИК протоколом и системой комманд для вашей техники, если она отличная от LG. Для этого понадобится TSOP и осциллограф, подключенный к его выходу. Направляем штатный пульт на тсоп, нажимаем нужную кнопку, получаем картинку и анализируем ее. В нашем случае получился протокол NEC (кодирование с помощью длительности пауз между синхроимпульсами), код комманды 08, что по табличке в инструкции на телевизор соответствует нажатой кнопке «вкл», адрес комманды 04 (про него в табличке ничего не написано). Осталось смоделировать такую-же картинку на МК.
Для начала получим на нашей ножке меандр с требуемой протоколом частотой заполнения лог единицы – 38кГц. Проще всего использовать один из каналов PWM, имеющийся во всех мегах. Настроим 8-разрядный таймер (16-разрядные оставим для более серьезных дел) в визарде CVAVR. В других компиляторах или с другими МК будет выглядеть по другому. Подробнее о настройках таймеров читайте в курсе avr123 и в даташите на свой МК.
Т.е. выбрали режим, когда при превышении значения регистра OCR0A ,счетчик таймера будет обнуляться, а выход OUT B (он же PD5), будет менять состояние на противоположное. Частота меандра определяется как ClockValue/CompareA/2= 2500/33/2=37.88 kHz. Потом я подстроил значение CompareA=32 по осциллографу. Особая точность частоты заполнения не требуется.
Сгенерив код получим следующую настройку для таймера:
- Код: Выделить всё • Развернуть
- // Timer/Counter 0 initialization
 // Clock source: System Clock
 // Clock value: 2500,000 kHz
 // Mode: CTC top=OCR0A
 // OC0A output: Disconnected
 // OC0B output: Toggle on compare match
 TCCR0A=0x12;
 TCCR0B=0x02;
 TCNT0=0x00;
 OCR0A=0x20;
 OCR0B=0x00;
Визард также предложит настроить ножку PD5 на выход, если мы забыли это сделать.
Запустим, проверим, что работает.
Чтобы снять импульсы и перевести ножку в ноль, запишем в регистры управления TCCR0A=0;TCCR0B=0;
Осталось, возпользовавшись библиотекой пауз, написать процедуры генерации сигналов по протоколу NEC.
- Код: Выделить всё • Развернуть
- #include <delay.h>
 #define PulseON TCCR0B=0x02;TCCR0A=0x12
 #define PulseOFF TCCR0B=0;TCCR0A=0
 void Gen_NEC_Byte(unsigned char dat) //Генерация одного байта по NEC
 {
 char i;
 for(i=0;i<8;i++)
 {
 PulseON; // синхроимпульс
 delay_us(560);
 PulseOFF;
 if(dat&1)delay_us(1690);else delay_us(560); //длительность паузы зависит от 1/0
 dat>>=1; //передаем от младшего бита к старшему
 }
 }
 void Gen_NEC_Code(unsigned char adr, unsigned char cmd) // Генерация всей комманды по NEC
 {
 PulseON; // стартовая последовательность
 delay_us(9000);
 PulseOFF;
 delay_us(4500);
 Gen_NEC_Byte(adr); // генерация адресса
 Gen_NEC_Byte(~adr); // генерация инверсии адресса
 Gen_NEC_Byte(cmd); // генерация комманды
 Gen_NEC_Byte(~cmd); // генерация инверсии комманды
 PulseON; // завершающий синхроимпульс
 delay_us(560);
 PulseOFF;
 }



 ((
((
 А если хозяину лень протянуть руку к пульту и он говорит роботу: включи телек - это другое дело. Осталось только распознавание речи сделать и научить робота находить направление на телевизор.
 А если хозяину лень протянуть руку к пульту и он говорит роботу: включи телек - это другое дело. Осталось только распознавание речи сделать и научить робота находить направление на телевизор.


