Перейти к содержанию
    

ИК ПДУ

Электронщики и программисты поделитесь пожалуйста опытом получения кода от ПДУ.

 

Написал и переделал уже 5 исходников на си и на асме, но не получаю в регистрах результата вобще ничего.

Результат отсылаю в СОМ-порт, но туда ничего не отправляется.

после нажатия кнопки пульта программа уходит неясно куда :rolleyes:

У меня есть алгоритм в котором после певого прерывания отсчитывают временные интервалы и изэтого прерывания МК и не выходит.

 

В форуме не нашел темы про RC5

 

 

:help: :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В форуме не нашел темы про RC5

 

А есть уверенность, что Ваш пульт выдает именно RC5 ?

А так всё просто - осциллограф в левую руку и http://www.sbprojects.com/knowledge/ir/ir.htm в правую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Электронщики и программисты поделитесь пожалуйста опытом получения кода от ПДУ.

Написал и переделал уже 5 исходников на си и на асме, но не получаю в регистрах результата вобще ничего.

Результат отсылаю в СОМ-порт, но туда ничего не отправляется.

после нажатия кнопки пульта программа уходит неясно куда :rolleyes:

 

Позвольте Вам не поверить, Вы не написали и переделали 5 исходников, а просто попытались методом тыка оживить

лежащие в инете исходники, не разобравшись в принципе, что же там происходит. Это путь хорош для сдачи лаб,

но не для запуска изделия. Там в принципе вообще нечего делать. И даже неважно в каком формате что то передается.

Для начала Вы должны записать все что приняли в память процессора, для чего считаете таймером задержки между

перепадами фронта сигнала, и пишете эти цифры в память. Для начала сгенерируйте таймером процессора какой нибудь

меандр, и заведите его обратно на вход, на котором осуществляется прием с пульта. И попробуйте словить свой собственный

меандр. Как только вы получите вменяемые цифры пойманного меандра, считайте задачка решена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

RC5 / RC6 нормально работает на асме исходник от Ридико Леонида. Только нужно немножко подправить инит таймера если используется не 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В форуме не нашел темы про RC5

 

Плохо искали, вот один из недавних проектов с RC5.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот тут мой вариант, который, как оказалось, расчудесно принимает и не-RC5 коды (только принятые значения не соответствуют документированным, но однозначное соответствие пульт-кнопка-код обеспечивается): http://arv.radioliga.com/downloads/html.rar

по ссылке архив html-документации, из которого должно быть все понятно (это не исходник!)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А для того чтобы посмотреть осциллографом сигнал ПДУ, нужно чтоб осциллограф был запоминающий, или можно и на аналоговом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А для того чтобы посмотреть осциллографом сигнал ПДУ, нужно чтоб осциллограф был запоминающий, или можно и на аналоговом?

 

С цифровым удобнее, безусловно. Но и обычный пойдет - нужно-то только понять, в каком из стандартов работает пульт. А дальше по букварю всё (одну из ссылок я давал выше).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сейчас я использую такой декодер RC-5 на Си для AVR:

 

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

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

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

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

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

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

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

#define PRE            64 //предделитель таймера 0
#define RC5_SLOT     1778 //длительность слота RC-5, мкс
#define RC5_LENGTH     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 signed char SampVal; //величина, полученная суммой выборок
static bool PreVal;         //значение педыдущего полу-интервала
static int RC5Code;         //принятый код
static char BitCounter;     //счетчик принятых битов
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)
{
  BitCounter = RC5_LENGTH;  //инициализация счетчика битов
  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(--BitCounter)              //декремент счетчика битов
        return;                     //переход к приему следующего бита
      SysVar = (RC5Code >> 6) & 0x3F; //номер системы
      ComVar = RC5Code & 0x3F;      //код команды
    }
  }
  BitCounter = RC5_LENGTH;          //загрузка счетчика битов
  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);
}

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Апликуха на Атмеле давно лежит, там и пульт и приемник. Почитайте.

 

Удачи!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"Товарищи ученые! У меня в подполе который год происходит подземный стук. Объясните, пожалуйста, как он происходит?" (с) классики

 

Автор задает довольно отстраненный и уклончивый вопрос на тему "у меня тут нечто не работает" - а ему дают ворох уклончивых ответов на тему "а у нас работает". Может на этом пути и можно чего-то добиться, но я преисполнен ядовитого скептицизма.

 

И кстати, конечно очень важно указание, что написано именно 5 исходников, из которых некоторые на си, а некоторые на асме. Теперь, конечно, всем все стало понятно и каждый сможет точно сказать, в чем именно проблема. Вот это я называю "детальное описание неполадки"... Да... ;-)

 

Действуйте так:

 

1) Введите в гугле WinScope. Найдете сразу программу WinScope 2.51 - осциллограф на звуковухе. (если нет цифрового осциллографа, это вполне сойдет)

 

2) Подключите ваш фотодатчик (если вы используете датчик на конкретную частоту несущую)и проверьте, видно чего-нибудь интересное, или нет. Несмотря на входные кондеры в звуковухе, сигнал, при его наличии, будет настолько ясным, что вы его сразу узнаете.

 

3) Если с вашим датчиком не получилось, подключите фотодиод или фототранзистор (убедившись что вы представляете как их вообще подключать) и проверьте вновь наличие сигнала.

 

4) Помедитировав над осциллограммами (и гуглом) убедитесь, RC5 это или нечто другое.

 

5) Если вы проделаете эти упражнения, у вас уже накопится критический уровень понимания для того, чтобы либо разобраться самому, либо сформулировать вопрос конкретно, с пониманием того, что же не работает на самом деле. ;-)))

Изменено пользователем RodionGork

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А когда-то давно вот такой приемник RC5 сотворил. Настройка периферии не показана. Потом этот код (правда уже вынесенный из обработчиков прерываний) скрестил с AVR-CDC (на меге8) - работает отлично...

//TSOP подключен к INT0
#include <mega16.h>
#include <stdio.h>

//МАКРОСЫ
#define RC5_SIZE 14
#define PIN_RC   2  /*приемный пин (номер в порту)*/
#define RC5_BIT  !(PORTD&(1<<PIN_RC))
//Временные пределы
#define T_MIN    20 /*длинный промежуток (корректируются в соответствии с частотой*/
#define T_MAX    34 /* тактирования таймера Т0)*/
#define T_MIN_SH 11 /*короткий промежуток*/
#define T_MAX_SH 17

//Глобальные переменные (используются  в обработчиках и основном цикле, либо для скорости)
unsigned char sct_bit;//Счетчик битов RC5
unsigned char rc5_buffer[RC5_SIZE];//буфер RC5
unsigned char fl_recieve_rc5; //флаг события приема
//структура принятого кода
struct rc5_str{
unsigned char startbit2;
unsigned char trigger;
unsigned char device;
unsigned char command;
               }rc5_code;

//--------------Обработчик прерывания по ИЗМЕНЕНИЮ уровня на int0------------------------//
interrupt [EXT_INT0] void ext_int0_isr(void)
{
static unsigned char centre;//флаг центра 
unsigned char error=1; //выставляем флаг ошибки, сбросим в теле обработчика, если все ОК...
unsigned char timer_rc5=TCNT0;//запоминаем значение счетчика
TCNT0=0;     
            
   switch (sct_bit){
                  case 0:
                  TCCR0=0x05; //запускаем таймер  (15.625 KHz)
                  rc5_buffer[sct_bit]=RC5_BIT;//записываем в эл.массива
                  sct_bit++;
                  centre=1;
                  break;
                                  
                  default:
                  if ((timer_rc5>T_MIN_SH)&&(timer_rc5<T_MAX_SH))//проверка кор. промежутка
                          {
                      if (centre){
                              centre=0;
                              error=0; 
                                 }
                      else   {
                         centre=1;
                         rc5_buffer[sct_bit]=RC5_BIT;
                         sct_bit++;
                         error=0;
                              }
                          }     
                  
                   if ((timer_rc5>T_MIN)&&(timer_rc5<T_MAX)){//проверка длинного промежутка
                                                  rc5_buffer [sct_bit]=RC5_BIT;
                                                  sct_bit++;
                                                  error=0;
                                                   }
                                                  
                   if (error){// если не попали ни в один из промежутков то
                           char i;
                           GICR|=0x00; //запрещаем прерывания по изм. по входу 
                           TCCR0=0x00; //(разрешим в обр. прер. по переполнению счетчика)
                           TCNT0=0;
                           sct_bit=0;
                           //очищаем буффер
                           for (i=0;i<RC5_SIZE;i++)rc5_buffer[i]=0;
                                }
                   
                    if (sct_bit==14){// если бит последний то:
                                 TCCR0 = 0x00; //останавливаем таймер
                                 TCNT0=0;
                                 sct_bit = 0;
                        //формируем из массива соответствующие коды 
                                 rc5_code.startbit2=rc5_buffer[1];
                                 rc5_code.trigger=rc5_buffer[2];
rc5_code.device=(rc5_buffer[3]<<4)|(rc5_buffer[4]<<3)|(rc5_buffer[5]<<2)|(rc5_buffer[6]<<1)|rc5_buffer[7];                    
rc5_code.command=(rc5_buffer[8]<<5)|(rc5_buffer[9]<<4)|(rc5_buffer[10]<<3)|(rc5_buffer[11]<<2)|(rc5_buffer[12]<<1)|rc5_buffer[13];
                                fl_recieve_rc5=1; //установили флаг приема
                                GIFR=0x40; // сбрасываем флаг прерывания по входу INT0
                                     }                                                       
                   
                  }

}
//=============================================================//

//------------ Обработчик прерывания по переполнению Т0 (таймаут)-----------------------//
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
        unsigned char i = 0;
        GICR|=0x00;
        TCCR0=0x00; //останавливаем таймер
        TCNT0=0;
        sct_bit=0;
        //очищаем буффер (его очищать необязательно)
        for (i=0;i<RC5_SIZE;i++) rc5_buffer[i]=0;
        GICR|=0x40; //разрешаем прерывания по входу
        GIFR=0x40;
}
//=============================================================//

...
//пример использования:
//отправляем по UART данные в случае приема кода
     if (fl_recieve_rc5){
     printf ("StartBit2 %d  Trigger %d  Device %d  Command %d",rc5_code.startbit2, rc5_code.trigger, rc5_code.device, rc5_code.command);
     fl_recieve_rc5=0;}
...

P.S. Код чуть подправил для красоты, поэтому могут остаться артефакты...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...