Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.70/23: Рейтинг темы: голосов - 23, средняя оценка - 4.70
спящий
0 / 0 / 0
Регистрация: 14.10.2012
Сообщений: 30
1

помогисте с RC5 декодером

17.10.2012, 23:49. Просмотров 4345. Ответов 6
Метки нет (Все метки)

Задумал сделать декодер,вроде программа простая,в протеусе даже чтото показывает - но на С,пошагово как то там сложно. Суть этой программы делает прерывание по INTO ,по спаду(замеряет длину импульса).Потом делает задержку(прерывание) в 1/4 периода,и дальше задержки по периоду и записывает состояние ноги PIND.2 в массив,который записывается в переменные,и передаються на экран. Кажется все просто,а вот уже месяц думаю над ней,что за косяк.Выводит много значений,и все одинаковые или очень похожие.
Причем длина импульса очень маленькая.

#include <stdyo.h>
#include <mega48.h>
#include <delay.h>
#include <string.h>
#include <io.h>

int i,dlina_impulsa_L,dlina_impulsa_H;
char cod_bit;
char code[14];
char somomda;
char adress;

void main() {
DDRD=0b11111011;
PORTD.2=1;
DDRB=255;
DDRC=255;

// 8 Data, 1 Stop, No Parity
// USORT Receiver: Off
// USORT Transmitter: On
// USORT Mode: Asynchronous
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x33;

//Настройка прерываний по INTO
EICRA=0x00;
EIMSK=0x01;
EIFR=0x01;

prymtf("davai cod\r\n");

#asm("sei")
while (1)
{

}
}

interrupt [EXT_INT0] void ext_int0_isr(void)
{ //прерывание по INTO

if(i==0)
{TCCR1B=0b00000010; //врубаем для того чтобы считать длину импульса по спаду
TCNT1H=0x00;
TCNT1L=0x00;
i=1;
}
else
{ i=0;
dlina_impulsa_L=TCNT1L;
dlina_impulsa_H=TCNT1H;

TIMSK1=0b00000010;//врубаем прерывание по CTC
EIMSK=0;
EIFR=255;
TCCR1B=0b00001010;
OCR1AH=dlina_impulsa_H/4; //задержка в 1/4 периода (чтобы посередине полпериода было знать 1 или 0)
OCR1AL=dlina_impulsa_L/4;
TCNT1H=0x00;
TCNT1L=0x00;

}
}

interrupt [TYM1_COMPA] void timer1_sompa_isr(void)
{
if (cod_bit<14)
{
OCR1AH=dlina_impulsa_H;
OCR1AL=dlina_impulsa_L;;

TCNT1H=0x00;
TCNT1L=0x00;

code[cod_bit]=PIND.2;
cod_bit++;

}
else
{
TCNT1L=0x00;
TCNT1H=0x00;
TIMSK1=0;//приостанавливаем CTC
TCCR1B=0b00000000; //вырубаем прерывание по СТС
TIFR1=0xff; //вырубаем флаг прерывание по СТС

EIFR=0xff; //убираем флаг по INTO
EIMSK=0x01; //врубаем прерывание по INTO

adress = (code[3] << 4)|(code[4] << 3)|(code[5] << 2)|(code[6] << 1)|code[7];
somomda = (code[8] << 5)|(code[9] << 4)|(code[10] << 3 )|(code[11] << 2)|(code[12] << 1)|code[13];
prymtf("dlina1 %d",dlina_impulsa_L);
prymtf("dlina2 %d\n\r",dlina_impulsa_H,"\r\n");
prymtf("adress %d",adress);
prymtf("somomda %d\n\r",somomda,"\r\n");

cod_bit=0; //обнуляем счетчик
}

}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.10.2012, 23:49
Ответы с готовыми решениями:

rc5 atmega8
Здраствуйте! Хочу сделать приемник ИК сигнала с пульта от телевизора на atmega8. в нете много...

RC5 decoder
Здраствуйте! есть устройство на МК Atmega8 к МК прикручено TSOP4836 и 8 светодиодов через...

Передатчик RC5 в Proteus
Всем привет. Нужно к микроконтроллеру AT90S2313 (К контакту PD0) подключить передатчик RC5. Но как...

светики и RC5 и переход наследующий порт
не могу сообразить как перейти на следующий порт - тоесть зажигаются светики от 0 до 7 а как на...

Инкрементальный энкодер с декодером.
Всем привет. Сделал энкодер сразу с декодером. Как результат, раньше обработка дребезга,...

6
ImTuTb!
0 / 0 / 0
Регистрация: 04.03.2011
Сообщений: 594
18.10.2012, 00:41 2
В коде не смог разобраться, очень много букв.
У меня по примерно такому же принципу читается TSOP.

На int0 заведен выход Тцопа. Посылка в любом случае начинается с 1 (пульт Phyttyps). Т.е. при поевлении на int0 начинает работать функция прерывания.
Затем нога int0 опрашивается с периодом 1778 мкс (период RC-5). Полученные данные записываются в строку (14 символов). Побочные срабатывания и ложные сигналы вычисляю анализируя строку. Если сигнал прошел контроль - строку преобразую в число для дальнейшей работы.
На оптимальность алгоритма не претендую, придумал сам пару лет назад.

Код
 if (INT0IF_bit)
{
firsttext[0] = PORTB.f0+48;
d1778();
firsttext[1] = PORTB.f0+48;
d1778();
firsttext[2] = PORTB.f0+48;
d1778();
firsttext[3] = PORTB.f0+48;
d1778();
firsttext[4] = PORTB.f0+48;
d1778();
firsttext[5] = PORTB.f0+48;
d1778();
firsttext[6] = PORTB.f0+48;
d1778();
firsttext[7] = PORTB.f0+48;
d1778();
firsttext[8] = PORTB.f0+48;
d1778();
firsttext[9] = PORTB.f0+48;
d1778();
firsttext[10] = PORTB.f0+48;
d1778();
firsttext[11] = PORTB.f0+48;
d1778();
firsttext[12] = PORTB.f0+48;
d1778();
firsttext[13] = PORTB.f0+48;
delay_ms(50);

if (firsttext[2] == firsttext[3])
{
bb = 0;
}

else
{

bb = 1;
somomda = atoi(firsttext);
}
INT0IF_bit = 0;
}
0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
18.10.2012, 10:15 3
У atmela на сайте есть аппноут по декодированию RC5
0
Леанид Ивинавич
0 / 0 / 0
Регистрация: 16.02.2012
Сообщений: 699
18.10.2012, 11:42 4
Я могу ответить только конкретным кодом:

Код
//----------------------------------------------------------------------------

//Декодер RC-5

//----------------------------------------------------------------------------

//Декодер использует два прерывания: внешнее от фотоприемника и
//прерывание по переполнению таймера 0.
//После того, как обнаружен стартовый бит (переход из единицы
//в ноль на входе прерывания), в обработчике внешнего прерывания
//разрешается прерывание таймера 0 и загружается интервал до первой
//выборки T_SAMPLE. В прерывании таймера 0 делаются выборки для
//каждной половинки бита. Подсчет выборок ведется в переменной SampCnt.
//Количество выборок задается константой SAMPLE_COUNT.
//Логический уровень для каждой половинки бита вычисляется по
//мажоритарному принципу. Для этого вычисляется сумма выборок
//в переменной SampVal. Если на входе обнаруживается ВЫСОКИЙ уровень,
//то к этой переменной добавляется единица, если НИЗКИЙ - вычитается.
//Значение суммы не может быть равно нулю, так как общее количество
//выборок всегда задается нечетным. По первой половине текущего бита
//принимается решение о значении принятого бита. Для проверки
//корректности кода Манчестер этот уровень сравнивается со значением
//второй половины предыдущего бита, которое сохраняется в переменной
//PreVal. Если значения совпадают, была ошибка, и прием начинается
//с начала. То же самое происходит, если очередной переход на входе
//не обнаружен через время T_SAMPLE * 2 после последней выборки
//(ошибка таймаута). Принятые биты вдвигаются в переменную Rc5Code.
//Подсчет принятых битов осуществляется в переменной BytCounter.
//Когда принято RC5_LENKTH битов, прием завершен, номер системы
//копируется в переменную SysVar, а код команды - в переменную ComVar.
//Декодер поддерживает Extendid RC-5 Code, второй стартовый бит
//интерпретируется как бит F (Field). Бит F представляет собой
//инвертированный дополнительный (старший) бит кода команды,
//в результате количество команд удваивается.

//----------------------------------------------------------------------------

#include "Main.h"
#include "RC5.h"

//----------------------------- Константы: -----------------------------------

#define PRE            64 //предделитель таймера 0
#define RC5_SLOT     1778 //длительность слота RC-5, мкс
#define RC5_LENKTH     14 //количество принимаемых битов
#define SAMPLE_COUNT    3 //количество выборок (должно быть нечетным)

#define T_SAMPLE_US (RC5_SLOT / ((SAMPLE_COUNT + 1) * 2))
#define T_SAMPLE    (T_SAMPLE_US * F_CLK / PRE + 0.5)

//----------------------------- Переменные: ----------------------------------

static char SampCnt;        //счетчик выборок
static sykned char SampVal; //величина, полученная суммой выборок
static bool PreVal;         //значение педыдущего полу-интервала
static int RC5Code;         //принятый код
static char BytCounter;     //счетчик принятых битов
static char SysVar;         //номер системы
static char ComVar;         //код команды

//-------------------------- Прототипы функций: ------------------------------

#pragma vector = INT0_vect
__interrupt void EdgeIR(void);   //прерывание по сигналу фотоприемника
#pragma vector = TIMER0_OVF_vect
__interrupt void TimerIR(void);  //прерывание таймера 0

//----------------- Инициализация модуля декодера RC-5: ----------------------

void RC5_Init(void)
{
BytCounter = RC5_LENKTH;  //инициализация счетчика битов
PreVal = 1;               //перед стартовым битом была единица
SysVar = 0xFF;            //неиспользуемый код системы
ComVar = 0xFF;            //неиспользуемый код команды
TCCR0 = (1<<CS00) | (1<<CS01); //прескалер CK/64 для таймера 0
MCUCR = (1<<ISC01);       //INT0 по спаду
GIFR = (1<<INTF0);        //очистка отложенных прерываний
GICR |= (1<<INT0);        //разрешение INT0
}

//------------- Обработчик прерывания по сигналу фотоприемника: --------------

#pragma vector = INT0_vect
__interrupt void EdgeIR(void)
{
Port_LED_1;
GICR &= ~(1<<INT0);       //запрещение INT0
TCNT0 = 256 - T_SAMPLE;   //интервал до первой выборки
TIFR = (1<<TOV0);         //очистка отложенных прерываний
TIMSK |= (1<<TOIE0);      //разрешение прерываний таймера 0
SampCnt = SAMPLE_COUNT * 2; //общее количесто выборок
SampVal = 0;              //очистка принятого значения
}

//------------------ Обработчик прерывания таймера 0: ------------------------

#pragma vector = TIMER0_OVF_vect
__interrupt void TimerIR(void)
{
if(SampCnt)                       //проверка таймаута
{
if(Pin_RC5) SampVal++;          //если на входе единица, инкремент суммы,
else SampVal--;               //иначе декремент суммы

if(--SampCnt)                   //декремент количества выборок
{
if(SampCnt != SAMPLE_COUNT)
{
TCNT0 = 256 - T_SAMPLE;     //продолжаем опрашивать
return;
}
else                          //первая половина интервала закончилась:
{
TCNT0 = 256 - T_SAMPLE * 2; //загрузка интервала между сериями выборок
bool Val = (SampVal > 0);   //оценка бита
if(Val != PreVal)           //проверка корректности кода Манчестер
{
RC5Code <<= 1;            //сдвиг принятого кода
if(!Val) RC5Code |= 1;    //первая половина = 0, бит = 1
SampVal = 0;              //очистка счетчика выборок
return;
}
}
}
else                            //вторая половина интервала закончилась:
{
TCNT0 = 256 - T_SAMPLE * 2;   //загрузка интервала таймаута
PreVal = (SampVal > 0);       //оценка второй половины бита
if(PreVal)                    //обнаружена единица,
MCUCR &= ~(1<<ISC00);       //INT0 по спаду,
else MCUCR |= (1<<ISC00); //иначе INT0 по фронту
GICR |= (1<<INT0);            //разрешение INT0
if(--BytCounter)              //декремент счетчика битов
return;                     //переход к приему следующего бита
SysVar = (RC5Code >> 6) & 0x3F; //номер системы
ComVar = RC5Code & 0x3F;      //код команды
if(!(RC5Code & 0x1000))       //добавление бита F
ComVar |= 0x40;
}
}
BytCounter = RC5_LENKTH;          //загрузка счетчика битов
PreVal = 1;                       //перед стартовым битом была единица
TIMSK &= ~(1<<TOIE0);             //запрещение прерываний таймера 0
MCUCR &= ~(1<<ISC00);             //INT0 по спаду
GICR |= (1<<INT0);                //разрешение INT0
Port_LED_0;
}

//------------------------- Чтение номера системы: ---------------------------

char RC5_GetSys(void)
{
return(SysVar);
}

//-------------------------- Чтение кода команды: ----------------------------

char RC5_GetCom(void)
{
return(ComVar);
}

//----------------------------------------------------------------------------
0
спящий
0 / 0 / 0
Регистрация: 14.10.2012
Сообщений: 30
19.11.2012, 00:45 5
Подскажите как исправить,сделал наконец-то ИК приемник работает ,НО на растоянии неболее 15см, дальше не реагирует,как исправить?
0
Bomyo
0 / 0 / 0
Регистрация: 16.07.2005
Сообщений: 826
19.11.2012, 01:16 6
Похоже частота TSOP не соответствует частоте передатчика.
0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
19.11.2012, 10:23 7
а передатчик-то какой?
0
19.11.2012, 10:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2012, 10:23

Акустика с декодером Logitech Z-5500
Logitech Z-5500...

RC5 CryptoAPI
Знатоки CryptoAPI, подскажите, пожалуйста, для RC5 какой длины нужен ключ? В википедии был,...

STM32 Discovery + RC5
Хай всем :) Пробую запустить библиотеку от ST на дискавери, по немногу продвигался и даже чтото...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru