Например TDA7294

Форум РадиоКот • Просмотр темы - [?] RC5+mega БЕЗ внешнего прерывания?
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Ср дек 17, 2025 10:36:46

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 12 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 08:18:10 
Встал на лапы

Зарегистрирован: Чт мар 05, 2009 08:15:25
Сообщений: 93
Рейтинг сообщения: 0
Здравствуйте, премногоуважаемые коты!

Без предисловий к делу: нужна Ваша помощь.

Дано: от одного самого умного инженера досталась плата на меге с ик-приемником (TSOP-31236) и кучей обвеса.
Сей премудрый инженер умудрился повесить приемник НЕ на внешнее прерывание, а на ногу PB.0
Программист написал под это дело программу, работает. Пришло время править код - у программиста аврал, не до того. Запрягли самого близко знакомого с мегами :)
Плата находится в массовом производстве, исправлять трассировку - нельзя.

Начал практиччески с нуля вспоминать си и меги в частности... Сам работаю для удовольствия в джаве.
Для лучшего понимания начал писать программу с нуля, а не перепиливать имеющуюся...

Итак...
Частота процессора 11059200 гц. Соответствующая константа FCLK наличествует в заголовке основого файла, и в проекте указана (CodeVision).

Есть старый код обработки данных:
Код:
//#define DivOvfTC2 37 // Константа выверена для FCLK=11059200 уточнена для FCLK=16MHz
//#define DivOvfTC2 (FCLK/296296) // 37 для FCLK=11059200
#define DivOvfTC2   (FCLK/291031) // 38 для FCLK=11059200

unsigned char cntOvfTC2=0,rc5command;
unsigned char RC5cnt14=0,RC5prev1=0x1,RC5prev2=0x1;
unsigned int RC5code=0xFFFF,RC5temp=0xFFFF,RC5delay=0;

// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void){
   unsigned char RC5tek;
   cntOvfTC2++;
   if (cntOvfTC2>=DivOvfTC2){
      // Константа DivOvfTC2 выверена для кварца на 11059200 МГц... (определена в RC5_T2.h)
      RC5delay++;
      if (RC5delay>562){
         RC5tek=PINRC5 & (1<<DD_RC5);
         if ((RC5tek==0) || (RC5prev1==0) || (RC5prev2==0)){
            RC5cnt14++;
            if ((RC5cnt14 & 1)==0){ // Есть очередной разряд
               RC5temp<<=1;  // Накопление результата
               if (RC5prev1==0) RC5temp|=1;
            }
            if ((RC5cnt14==28) && ((RC5temp & 0xF0)!=0xF0)){
               RC5code=RC5temp;
               RC5delay=0;
               rc5command=RC5code&0x3F;
            }
            RC5prev2=RC5prev1; RC5prev1=RC5tek;
         }else{
            RC5cnt14=0; RC5temp=0x00;
         }
      }
      cntOvfTC2=0;
   }
}


Далее в основном цикле программы опрашиваются переменные и выводится полученная команда на экран:
Код:
        if (RC5code != 0xFFFF){
            clearBuffer();
            flushBuffer();
            delay_ms(100);
               
            putNumberIntoBuffer(0,rc5command,4);
       
            RC5code=0xFFFF; // Нажатие кнопки ПДУ отработано...
            flushBuffer();   
        }


Но, работает это дело очень криво: часть кнопок не работает. Если сработало - выдает не всегда одинаковый код на дисплей.

Есть ли у кого-нибудь опыт "разборок" с RC5 без внешнего прерывания, чисто по таймерам?
Буду очень благодарен за помощь!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 09:29:16 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 74
Зарегистрирован: Пн июн 18, 2012 12:01:04
Сообщений: 650
Откуда: Челябинская область, Копейск
Рейтинг сообщения: 0
Цитата:
Сей премудрый инженер умудрился повесить приемник НЕ на внешнее прерывание, а на ногу PB.0

Какой камень, может на PB0 имеется всетаки какое прерывание? Обязательно INTn использовать чтоли, можно любой вектор использовать, а событие обрабатывать уже как угодно.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 09:34:54 
Опытный кот
Аватар пользователя

Карма: 8
Рейтинг сообщений: 106
Зарегистрирован: Ср фев 22, 2012 01:25:21
Сообщений: 882
Рейтинг сообщения: 0
Цитата:
Сей премудрый инженер умудрился повесить приемник НЕ на внешнее прерывание, а на ногу PB.0
Я тоже делал декодирование не по внешнему прерыванию, все отлично работает (мне даже больше нравится такой вариант чем по внешнему прерыванию), просто настраиваеш таймер счетчик на частоту в 10 раз больше чем частота RC5 и в каждом прерывании анализируеш состояние линии.....


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 11:07:50 
Встал на лапы

Зарегистрирован: Чт мар 05, 2009 08:15:25
Сообщений: 93
Рейтинг сообщения: 0
Камень AtMega8, там нет вектора...

По поводу частоты - можете пример дать рассчета или Вашего кода? Частоту нашего камня я писал в первом посте...


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 11:15:22 
Прорезались зубы

Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Пт май 18, 2012 23:12:23
Сообщений: 249
Рейтинг сообщения: 0
программній прием одним таймером, частота опроса желательно >5кГц:
http://we.easyelectronics.ru/reptile/bi ... ik-du.html


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 11:23:37 
Говорящий с текстолитом
Аватар пользователя

Карма: 11
Рейтинг сообщений: 143
Зарегистрирован: Пт дек 28, 2012 21:56:46
Сообщений: 1518
Откуда: St. Petersburg
Рейтинг сообщения: 0
Johnson писал(а):
Камень AtMega8, там нет вектора....

Почему? В меге 8 есть поддержка внешнего прерывания (ноги PD2 и PD3).

Если вы имели ввиду конкретно пин PB0, то по нему тоже можно прерывание сгенерить. Его альтернативная функция - ICP1 - Input Capture Pin 1.

Atmel datashit писал(а):
When a change of the logic level (an event) occurs on the Input Capture Pin (ICP1), alternatively
on the Analog Comparator Output (ACO), and this change confirms to the setting of the edge
detector, a capture will be triggered. When a capture is triggered, the 16-bit value of the counter
(TCNT1) is written to the Input Capture Register (ICR1). The Input Capture Flag (ICF1) is set at
the same system clock as the TCNT1 value is copied into ICR1 Register. If enabled (TICIE1 =
1), the Input Capture Flag generates an Input Capture interrupt. The ICF1 Flag is automatically
cleared when the interrupt is executed. Alternatively the ICF1 Flag can be cleared by software
by writing a logical one to its I/O bit location.


При изменении уровня на ноге происходит копирование значения TCNT1 в регистр ICR1, одновмеренно устанавливается флаг ICF1, и если TICIE1 = 1 то генерируется прерывание.

В сообщении ниже также уже ответили, собственно :)

_________________
Изображение only pure true norwegian blackx Изображение


Последний раз редактировалось blackx Пн фев 18, 2013 11:39:24, всего редактировалось 2 раз(а).

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 11:29:29 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 74
Зарегистрирован: Пн июн 18, 2012 12:01:04
Сообщений: 650
Откуда: Челябинская область, Копейск
Рейтинг сообщения: 0
Johnson писал(а):
Камень AtMega8, там нет вектора...

Как нет, а ICP1 чем не вектор, возможно через него все и работает.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 12:57:08 
Встал на лапы

Зарегистрирован: Чт мар 05, 2009 08:15:25
Сообщений: 93
Рейтинг сообщения: 0
Спасибо за ответы!
Порылся в коде - нет, этот вектор не используется.

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

Хотя тут немного не понимаю, таймер настроил в точности как в существующем проекте, код использовал тот же, а результат разный...

Про прерывание ICP1 - можете пример показать, как настроить его и использовать для этих целей?


PS: Про отсутствие векторов - имел в виду именно эту ногу. Про вектор ICP1 не слышал раньше...

polyname, спасибо большое за код! Буду разбираться и кастрировать его под конкретный пульт! :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Пн фев 18, 2013 13:24:10 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 74
Зарегистрирован: Пн июн 18, 2012 12:01:04
Сообщений: 650
Откуда: Челябинская область, Копейск
Рейтинг сообщения: 0
На асме настраивается так:

cbi DDRB, 0
.......
ldi r16, (1<<TICIE1)
out TIMSK, r16 ; Включаем вектор TIMER1 CAPT
in r16, TIFR
out TIFR, r16
sei
.........

MAIN_loop:
rjmp MAIN_loop ; Go again

TMR1_ICP:
.....
reti


P.S. еще подтяжку забыл: sbi PORTB,0


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Чт фев 21, 2013 11:08:22 
Встал на лапы

Зарегистрирован: Чт мар 05, 2009 08:15:25
Сообщений: 93
Рейтинг сообщения: 0
Блин, весь мозг себе сломал с этим капчером.

Есть у кого-нибудь соображения, как с его помощью читать команду с RC5?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Чт фев 21, 2013 11:47:50 
Опытный кот
Аватар пользователя

Карма: 8
Рейтинг сообщений: 106
Зарегистрирован: Ср фев 22, 2012 01:25:21
Сообщений: 882
Рейтинг сообщения: 0
Вечером соображу, поделюсь.....


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: [?] RC5+mega БЕЗ внешнего прерывания?
СообщениеДобавлено: Чт фев 21, 2013 12:42:34 
Встал на лапы

Зарегистрирован: Чт мар 05, 2009 08:15:25
Сообщений: 93
Рейтинг сообщения: 0
Вообщем, нашел исходник, слегка переделал его на прерывание ICP1...
Работает даже более, чем идеально: команды посылаются каждые 114мс, и слишком часто обрабатываются нажатия.

Пока решил эту проблему простым таймаутом, но хотелось бы более правильно: обработкой третьего бита команды.

Полностью "переварить" код пока не могу, прощу помощи.

Итак, код, который работает:

Код:
unsigned char rc5command,rc5temp1,rc5temp2;
unsigned int rc5time,rc5data;

#define rc5_max 1400
#define rc5_min 900

void rc5init(){
   TCCR1A = 0;TCCR1B = 1<<CS11|1<<ICNC1;
   TCNT1H = 0;TCNT1L = 0;
   OCR1AH = 0X0B;OCR1AL = 0XB8;
   ICR1H = 0;ICR1L = 0;
   TIFR = 1<<ICF1|1<<OCIE1A;
   TIMSK |= 1<<TICIE1|1<<OCIE1A;
   rc5temp1=0;
    rc5temp2=0;
    rc5data=0;
}

void rc5_recive_bit(void){
   if (rc5temp1 == 0x00){
      TCCR1B |= 1<<ICES1|1<<ICNC1;
      rc5temp1 = 0xff;
      if ((rc5time > rc5_min) && (rc5time < rc5_max)){
         rc5data = (rc5data << 1)& 0xfffe;
         ++rc5temp2;
         goto rbok;
      }
      if ((rc5time > (rc5_min*2)) && (rc5time < (rc5_max*2))){
         rc5data = (rc5data << 2)& 0xfffc;
         rc5temp2+=2;
         goto rbok;
      }
   }else{
      TCCR1B = (1<<CS11)|(1<<ICNC1);
      rc5temp1 = 0;
      if ((rc5time > rc5_min) && (rc5time < rc5_max)){
         rc5data = (rc5data << 1) | 0x0001;
         ++rc5temp2;
         if (rc5temp2 == 27){
            ++rc5temp2;
            rc5data = (rc5data << 1)& 0xfffe;
         }
         goto rbok;
      }
      if ((rc5time > (rc5_min*2)) && (rc5time < (rc5_max*2))){
         rc5data = (rc5data << 2) | 0x0003;
         rc5temp2+=2;
         if (rc5temp2 == 27){
            ++rc5temp2;
            rc5data = (rc5data << 1)& 0xfffe;
         }
         goto rbok;
      }
   }
   rc5init();
   return;
   rbok:
   TIFR = 1<<ICF1;
}

interrupt [TIM1_CAPT] void timer1_capt_isr(void){
   unsigned char templ,temph,ttst=0;
   templ= ICR1L;temph= ICR1H;
   rc5time = templ;
   rc5time = rc5time | (temph << 8);
   TCNT1H = 0;TCNT1L = 0;
   ICR1H = 0;ICR1L = 0;
   if (rc5temp2 == 0){
      TCCR1B |= (1 << ICES1)|(1<<ICNC1);
      TIFR = (1 << ICF1);
      rc5temp1 = 0xff;
      ++rc5temp2;
   }else
        rc5_recive_bit();
   
   if (rc5temp2 == 28){
      rc5command = 0;
      while (ttst != 7){
         switch (rc5data & 0x0003){
            case 0x01:   rc5temp2 = 1;break;
            case 0x02:   rc5temp2 = 0;break;
         }
         rc5command |= rc5temp2 << ttst;
         rc5data >>= 2;
         ++ttst;
      }
      rc5init();
   }
}

interrupt [TIM1_COMPA] void timer1_compa_isr(void){
    rc5init();
}


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


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

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


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

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y