нужно раскодировать данные передаваемые с ИК пульта от телека. Протоколы смотрел,но ничего подходящего не нашел. Решил сам их добыть написав свой протокол декодирования. Пощупав осциллографом получил что при нажатии любой кнопки пульт просаживает линию на 3 мс затем отпускает на 3 мс. после начинает просаживать перед каждым битом на время около 500 мкс затем,если 0 отпускает линию на 1,5 мс, если 1 линия в плюсе 2,5 мс и так 16 бит.+ в конце передачи я так понимаю бит завершения передачи линия в плюсе 4 мс. При нажатии любой кнопки первые 8 бит одинаковые, вторые 8 бит меняются. в моем протоколе включено считывание начала передачи и 16 бит данных. Стоп-бит я упускаю.
Решил все это считывать с помощью прерывании и таймера для отсчитывания времени удержания в плюсе.
Все прерывания срабатывают, но считывается всякий бред в основном 1. Грешил на время отсчитываемое таймером,но все варианты предделителя перепробовал, В OCR0 все возможные варианты вписал. Может алгоритм не верный, не могу понять... Спасибо за ранее!!!
Спойлер
Код: Выделить всё
#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)
{
}
}- Вложения
-
- 2018-03-18_21-58-41.png
- (28.84 КБ) 311 скачиваний

