Реализация на атмеге8 16МГц (вполне можно и на меньшей частоте, для моего проекта нужно было именно 16) на 8-bit Timer/Counter2 в режиме CTC.
Спойлер
Код: Выделить всё
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define PORT_output 0
#define on(X) PORTB|=(1<<(X))
#define off(X) PORTB&=~(1<<(X))
#define invert(X) PORTB^=(1<<(X))
#define pin_on(X) (PINB&(1<<(X)))
//#define ID_code 0xB9
unsigned char i,j;
unsigned char buf_NEC[4] = {0xB9, 0x46, 0, 0};
void timer_1204_init(void);
void transmit_NEC(unsigned char comands);
void timer_off(void);
void decode_bit(void);
void decode_bit(void)
{
if (pin_on(PORT_output) != 0)
{
OCR2 = 70; //560us
}
else
{
if (((buf_NEC[i-1]&(1<<j++)) != 0)&&(pin_on(PORT_output) == 0))
{
OCR2 = 211; //1690us
}
else
{
OCR2 = 70; //560us
}
}
if (j > 7)
{
i++;
j = 0;
}
}
//прерывание сравнения
ISR(TIMER2_COMP_vect)
{
invert(PORT_output);
switch (i)
{
case 0:
OCR2 = 70; //4,5ms
i++;
break;
case 1:
TCCR2&=~(1<<CS21); //предделитель 128
decode_bit();
break;
case 2:
decode_bit();
break;
case 3:
decode_bit();
break;
case 4:
decode_bit();
break;
case 5:
if (pin_on(PORT_output) != 0)
{
OCR2 = 70; //560us
}
else
{
j = 0;
i = 0;
timer_off();
}
break;
}
}
void timer_1204_init(void)
{
TCCR2 |= (1<<CS20)|(1<<CS21)|(1<<CS22)|(1<<WGM21); //предделитель 1024
TIMSK |= (1<<OCIE2); //прерывание по переполнению
sei();
}
void timer_off(void)
{
TCCR2&=~((1<<CS20)|(1<<CS21)|(1<<CS22)); //предделитель 1024
TIMSK&=~(1<<OCIE2); //прерывание по переполнению
}
void transmit_NEC(unsigned char comands)
{
buf_NEC[2] = comands;
buf_NEC[3] = ~comands;
on(PORT_output);
timer_1204_init(); //запускаем счетчик
OCR2 = 140; //9ms
i = 0;
}
int main(void)
{
DDRB|=(1<<0);
off(PORT_output); //выход на транзистор IrDa
/* Replace with your application code */
while (1)
{
transmit_NEC(0x12);
_delay_ms(200);
transmit_NEC(0x13);
_delay_ms(400);
}
}Единственно там еще не хватает буфера для передачи!
А для подключения диода задействовать Timer1 для реализации модуляции на 38,222кГц на той же ноге PB1 (OC1A)
