asis-kbr.ru

автоматические системы и системы безопасности
Текущее время: 13 дек 2018, 12:42

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ 1 сообщение ] 
Автор Сообщение
 Заголовок сообщения: Работа с ИК протоколом RC5
СообщениеДобавлено: 22 мар 2013, 14:55 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 19 янв 2012, 12:52
Сообщения: 575
Откуда: KBR
Библиотечка от Л.И.
взял отсюда http://radiokot.ru/forum/viewtopic.php? ... e654503ea4

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

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

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

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

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

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

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

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

#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;      //код команды
      if(!(RC5Code & 0x1000))       //добавление бита F
        ComVar |= 0x40;
    }
  }
  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);
}

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


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ 1 сообщение ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB