Для реализации достаточно иметь одну свободную ножку порта, желательно с функцией 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;
}