Вс мар 18, 2018 21:17:27
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define IR_sens 3
#define IR_DDR DDRD
#define IR_PIN PIND
#define IR_PORT PORTD
uint16_t DATA=0;
uint16_t DATA_buf=0;
uint16_t i=0;
uint8_t START_flag=0; // флаг о начале приема
void init_INT1(void)
{
MCUCR|=(1<<ISC11)|(0<<ISC10); //генерация прерывания по падающему фронту
GICR|=1<<INT1; // включаем прерывание по INT1
}
void init_T0(void)
{
TCCR0=(0<<WGM00)|(1<<WGM01)|(1<<CS02)|(0<<CS01)|(1<<CS00); // делитель 1024
}
ISR (TIMER0_COMP_vect)
{
TIMSK&=~(1<<OCIE0); // отключаем прерывание по таймеру
if(i<16)
{
if((IR_PIN&(1<<IR_sens)))
DATA|=1<<i;
else
DATA|=0<<i;
i++;
}
if(i==16)
{
START_flag=0;
DATA_buf=DATA;
DATA=0;
GICR&=~(1<<INT1); //отключаем прерывание по INT1
MCUCR=(1<<ISC11)|(0<<ISC10);// восстанавливаем прерывание INT1 по падающему фронту
GICR|=(1<<INT1); //включаем прерывание по INT1
i=0;
}
};
ISR (INT1_vect)
{
if(!START_flag) // если флаг старт не установлен проверяем на достоверность начала приема
{
_delay_us(800); //
if((IR_PIN&(1<<IR_sens))==0) // проверяем достоверность начала приема
START_flag=1; // если достоверно устанавливаем флаг стат
}
else // если флаг установлен
{
if((MCUCR&(0x03<<2))==0xC) // проверяем по какому фронту прерывание iNT1,
{
// если прерывание было установлено по восходящему фрнту начинаем отсчитывать время для считывания бита
TIMSK|=1<<OCIE0; // включение прерывание таймера
TCNT0=0x00;
}
else
{
GICR&=~(1<<INT1); //отключаем прерывание по INT1
MCUCR|=(1<<ISC11)|(1<<ISC10); // устанавливаем прерывание по восходящему
GICR|=(1<<INT1); //включаем прерывание по INT1
}
}
//GIFR|=1<<INTF1;
};
int main(void)
{
IR_DDR&=~(1<<IR_sens); // ножку подключенную к датчику настравиваем на вход. данные только входные
IR_PORT&=~(1<<IR_sens); // ножку подтягиваем.
init_T0();
init_INT1();
OCR0=15;
sei();
while (1)
{
}
}
Пн мар 19, 2018 07:12:39
Пн мар 19, 2018 10:01:49
Пн мар 19, 2018 10:06:54
вы читать умеете?ROMan2947 писал(а):моя диаграмма разве схожа с этим протоколом?
я вашу диаграмму и смотреть не стал -уверен, что в упомянутые 99% попадетARV писал(а):Вот здесь полностью универсальный алгоритм приема ИК-кодов, проверенный неоднократно и подходящий для 99% всех типов пультов.
Пн мар 19, 2018 17:50:10
#include <avr/io.h>
#include <util/delay.h>
#define IR_sens 3
#define IR_DDR DDRD
#define IR_PIN PIND
#define IR_PORT PORTD
#define OC1A 5
#define step 50
uint16_t DATA=0;
uint16_t i=0;
void TIMER_instal(void)
{
DDRD|=(1<<OC1A);
TCCR1A=(1<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(0<<FOC1A)|(0<<FOC1B)|(1<<WGM11)|(1<<WGM10);
TCCR1B=(0<<ICNC1)|(0<<ICES1)|(0<<WGM13)|(1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10);
}
void read_TIMER(uint8_t data)
{
switch(data)
{
case 0xC8:
if(TCCR1A&(1<<COM1A1))
{
if((OCR1A+step)<=0x3FF) OCR1A+=step;else OCR1A=0x3ff; // увеличиваем обороты
}
break;
case 0x48:
if(TCCR1A&(1<<COM1A1))
{
if(((OCR1A-step)>0x00)&((OCR1A-step)<0x3FF)) OCR1A-=step; else OCR1A=0; // убавляем обороты
}
break;
case 0xF4: TCCR1A|=(1<<COM1A1); break; // старт
case 0xA8: TCCR1A&=~(1<<COM1A1);break; // стоп
}
}
uint8_t IR_kod(void)
{
DATA=0;
if(!(IR_PIN&(1<<IR_sens)))
{
_delay_us(1100);
if(!(IR_PIN&(1<<IR_sens)))
{
_delay_ms(7);
if(IR_PIN&(1<<IR_sens))
{
DATA|=(unsigned int)1<<i;
_delay_ms(1);
}
else
{
DATA|=(unsigned int)0<<i;
}
while(i<=15)
{
i++;
_delay_ms(2);
if(IR_PIN&(1<<IR_sens))
{
DATA|=1<<i;
_delay_us(1050);
}
else
{
DATA|=0<<i;
}
}
i=0;
}
}
DATA=DATA>>8;
read_TIMER(DATA);
}
int main(void)
{
IR_DDR&=~(1<<IR_sens); // ножку подключеную к датчику настравиваем на вход. данные только входные
IR_PORT|=(1<<IR_sens); // ножку подтягиваем.
TIMER_instal();
while (1)
{
IR_kod();
}
}