Протокол ДУ RC5 нужна помощь!

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Родился
Аватара пользователя
Сообщения: 8
Зарегистрирован: Чт дек 13, 2012 11:55:26

Сообщение Pawlo »

Доброго времени суток, уважаемые форумчане!
Уже который день бьюсь над одним вопросом. Перечитал кучу информации, но не могу никак дойти до логического завершения.
Суть вопроса такова:написал программку декодирования сигналов с пульта ДУ, но никак не могу заставить МК выполнить нужное мне действие при нажатии определенных кнопок на пульте. Подскажите, как правильно организовать выполнение данного действия. Пишу в CVAVR, код прилагаю. Буду рад любой помощи... Заранее спасибо!

Код: Выделить всё

#include <mega8.h>
#include <delay.h>
// Временные пределы

#define Tmin 45//длинный промежуток
#define Tmax 85
#define TminK 10 //короткий промежуток
#define TmaxK 45
//Так ка ничего идеально нет то и импульсы не бывают идеально четкими, поэтому мы ставим пределы на измерения времени короткого промежутка и длинного. Для короткого от 10 тиков до 45( 1 тик при скорости таймера 31.250 кГц это 32 микросекунды),
//а для длинного от 45 до 85 тиков. Если у вас супер навороченый пульт с идеальными импульсами, можете сделать промежутки поменьше.
//Далее задаем необходимые переменные:

unsigned char sct_bit = 0;              //Счетчик битов RC5 (показывает какой бит считывается)
unsigned char RC5_buffer [14];   //Буфер RC5 (собственно сюда будут складироваться наши биты)
bit centre = 0;                                    //Флаг центра (Флаг попадания в впадину короткого импульса)
bit not_korr = 0;                                //Флаг попадания в промежутки (Если импульсы не попадут в наши промежутки)
unsigned char Timer = 0;              //число в счетчике таймера          (Наши тики именно их и будем проверять)
unsigned char trigger = 0;             //переменная тригера           
unsigned int device = 0;                //переменная адреса ПДУ
unsigned char command = 0;     //переменная для команды
//В итоге то что нам нужно будет в переменной command.

// Функция очистки буфера
void rc5_cl_buf(void){  
char i = 0; 
for (i=0; i<14; i++){ RC5_buffer [i] = 0; }
}

//Вторая будет останавливать таймер:

void rc5_ti_stop(void){ //остановка таймера
  GICR |=0x00; //Внимание!  
  TCCR0=0x00;// Останавливаем таймер         
  TCNT0=0x00; //Обнуляем тики
  sct_bit = 0; //обнуляем счетчик битов 
}

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{ 
PINC.0 = 1;
Timer = TCNT0; //запоминаем значение счетчика  
TCNT0 = 0; //обнуляем счетчик
not_korr = 1; 
 
if(sct_bit==0)
  {                                // если бит первый
  TCCR0 = 0x04;                        //запускаем таймер (31.250 KHz)
  RC5_buffer [sct_bit] = !PIND.2;//записываем  бит  в массив
  sct_bit++; //+1 к счётчику принятых битов  
   centre = 1;  
   }else
      {
     if ((Timer>TminK)&&(Timer)) // проверка короткого промежутка
      if (centre) { 
               centre = 0;
               not_korr = 0; 
                        } 
                        else
                        {
                                    centre = 1;
                                    RC5_buffer [sct_bit] = !PIND.2;
                                    sct_bit++;
                                    not_korr=0;
                                  };  

                                                                         
   if ((Timer>Tmin)&&(Timer))// проверка длинного промежутка
       RC5_buffer [sct_bit] = !PIND.2;
       sct_bit++;
       not_korr = 0; 
    
                                                                 };  
   if (not_korr == 1) { // если не попали ни в один из промежутков то  
     rc5_ti_stop(); //останавливаем таймер
     rc5_cl_buf();  //очищаем буфер
     };  

   if (sct_bit == 14){ // если бит последний то 
     rc5_ti_stop();    //останавливаем таймер

     trigger = RC5_buffer [2]; //формируем переменную тригера 

device = (RC5_buffer [3] << 4)|(RC5_buffer [4] << 3)|(RC5_buffer [5] << 2)|(RC5_buffer [6] << 1)|RC5_buffer [7]; //формируем адрес ПДУ 
command = (RC5_buffer [8] << 5)|(RC5_buffer [9] << 4)|
(RC5_buffer [10] << 3 )|(RC5_buffer [11] << 2)|(RC5_buffer [12] << 1)|RC5_buffer [13]; //формируем команду
 device = 0;   
//А ВОТ тут загвоздка!!!!!!!! 
switch (command) {
    case 10: PORTC.0 = 1; delay_ms(500);PORTC.0 = 0;
    break;
    case 03: PORTC.1 = 1; delay_ms(500);PORTC.1 = 0;
    break;   
    case 01: PORTC.2 = 1; delay_ms(500);PORTC.2 = 0;
    break;
   
    default:
    delay_ms (385);
   

}
GIFR=0x40; // сбрасываем флаг прерывания по входу int.0                                                   
}; 
 }



// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
 rc5_ti_stop();      //останавливаем таймер
rc5_cl_buf();        //очищаем буфер
GICR|=0x40; //разрешаем прерывания по входу
GIFR=0x40;      //сбрасываем флаг прерывания (если произошло)
}
void main(void)
{


// Port C initialization
// Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=In Func0=In 
// State6=T State5=1 State4=1 State3=1 State2=1 State1=T State0=T 
PORTC=0x00;
DDRC=0xFF;

/ External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
GICR|=0x40;
MCUCR=0x00;
GIFR=0x40;
}
 
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 330
Зарегистрирован: Чт июн 23, 2011 07:55:51

Сообщение korsaj »

У вас в программе нет главного цикла!
Реклама
Родился
Аватара пользователя
Сообщения: 8
Зарегистрирован: Чт дек 13, 2012 11:55:26

Сообщение Pawlo »

korsaj писал(а):У вас в программе нет главного цикла!
главный цикл присутствует, я просто его не выложил... сравнение команд производить в главном цикле или же в обработчике прерываний?
Ответить

Вернуться в «Периферия»