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

Распознование Команд С Ик Пульта


Nex

Рекомендуемые сообщения

... Допустим если я пишу в основном цикле if(command==13) {PORTB.1=1} то все. процесс декодирования начинает давать сбои. Но. если я тоже самое пишу в прерывании, то все идет как по маслу. Не знаю даже где и капать.

Капайте :) Пока вы проверяете command, она в обработчике может и поменятся... Используйте промежуточную переменную:

while(1)
{
#asm("cli")
temp_command=command;
#asm("sei")
//..

if(temp_command==13) {PORTB.1=1}
//..
}

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

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

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов 59
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Не поверите, первое, что пришло в голову - это создать промежуточную переменную, которая в обработчике прерывания при успешном декодировании принимала значение этой комманды, а в основном цикле программы при обрабоке этой переменной она сбрасывалась в ноль. поэтому проблема не распознать комманду, а её декодировать. чтож обьясню более подробно: при пустом осн. цикле декодирование идет с 1 раза. тоесть первый же пакет с пульта распознается, при добавлении в осн. цикл совершенно не требующей уйму процессорного времени программу декодирование идет значительно хуже. А так как я могу понять, что имненно идет не так: либо не попали на импульс, либо таймер переполен, я могу судить о сбоях. так вот при все этом начинается сбой как и по переполнению таймера, там и при поиске импульсов. Ну на таймер грешить врятли. там мало того что 4 строчки кода, так и тупить он вроде не должен. получается что прерывание по int0. Кстати попробуйте сами, ради интереса. с 1 стр поста возьмите код(rc5.txt) и допишите в осн цикл "if (command==13) {PORTB.0=1};" только в самом коде кстати ошибка, там где таймер запускается в прерывании int0 вместо значения 05 подставьте 04.

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

...только в самом коде кстати ошибка, там где таймер запускается в прерывании int0 вместо значения 05 подставьте 04.

Не поверите, для 16-ти МГц и выставленных пределах в тиках 0x05 - самое то...

Насчет остального - вы строку:

delay_ms (385); //пауза не обязательно - чтобы реакция кнопок была помедленнее...  

в обработчике закомментировали, надеюсь? Оно там только для отладки было...

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

  • 4 месяца спустя...
  • 4 недели спустя...
  • 10 месяцев спустя...

а можете растолковать (читал книги но не понял) чем отличается GICR от GIFR? читал что у GIFR INTFx=1 если произошло прерывание на входе INTx(GICR)...помогите понять по листингу программы RC5, да и зачем использовали PORTD.7

Изменено пользователем ems2811
Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...

вот мой агрегат =) ссылка

проект открытый и написан на bascom, поэтому разобраться с алгоритмом думаю будет просто.

по поводу GIFR, в этот регистр записывается бит когда прерывание произошло. после ухода на обработку прерывания, этот бит сбрасывается. Зачем оно надо? Все просто, например пришло первое прерывание, начали его обрабатывать, и не успели выйти из обработчика, как приходит следующее прерывание. Если бы не было этого регистра, то второе прерывание так и осталось бы не обработанным. А так процессор, закончив обработку первого прерывания, проверяет значение этого регистра, и если он не пуст, то значит второе прерыванеи произошло и его тоже нужно обработать и начинается его обработка. Для каждого типа прерывания существует свой регистр хранения. GIFR это для внешних INT0, INT1. Для компаратора например этим занимается регистр ACSR.

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

  • 1 год спустя...

Здравствуйте новички и профили... скажите могу ли я использовать TSOP1838 для RC5 ну для частоты в 36 килогерц, если нет пожалуйста подскажите как мне получить 38килогерц? на atmega8

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

  • 11 месяцев спустя...

Всем привет!

Принимаю команды с пульта RC5 и вывожу код на индикаторы (статья находится здесь). Но я пишу на CVAVR, поэтому код немного изменён.

// Декодирование сигналов протокола RC5

#include <mega8.h>
#include <delay.h>

// Временные пределы
#define Tmin 40 // длинный промежуток
#define Tmax 68
#define TminK 22 // короткий промежуток
#define TmaxK 34

//------------------0-----1-----2-----3-----4                     
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66,
//------------------5-----6-----7-----8-----9
                 0x6D, 0x7D, 0x07, 0x7F, 0x6F};      

volatile unsigned char segcounter = 0;
volatile int display1 = 0;
volatile int display2 = 0;

unsigned char sct_bit = 0; // Счетчик битов RC5
unsigned char RC5_buffer [14]; // Буфер RC5
unsigned char centre =  0; // Флаг центра
unsigned char not_korr = 0; // Флаг попадания в промежутки
unsigned char Timer = 0; // число в счетчике таймера
unsigned char command = 0; // переменная для команды

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

// функция остановки таймера
void rc5_ti_stop(void)
{
GICR = 0x00;
TCCR0 = 0x00;
TCNT0 = 0;
sct_bit = 0;
}

// Обработчик прерывния по переполнению Т0
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{  
rc5_ti_stop(); //останавливаем таймер
rc5_cl_buf(); //очищаем буфер
GICR |= (1 << INT0); // разрешаем прерывания по входу INT0
GIFR |= (1 << INTF0); // сбрасываем флаг прерывания
// (если произошло)
}

// Обработчик прерывния по переполнению Т1
// Динамическая индикация
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{  
PORTB = 0xFF;
PORTC = (1 << segcounter);

switch (segcounter)
{  
case 0:
PORTB = ~(SEGMENTE[display1]);
break;
case 1:
PORTB = ~(SEGMENTE[display2]);
break; 
}
if ((segcounter++) > 0)
segcounter = 0;
}

// Обработчик внешнего прерывания INT0
interrupt [EXT_INT0] void ext_int0_isr(void)  
{
Timer = TCNT0; // запоминаем значение счетчика  
TCNT0 = 0;     // обнуляем счетчик
not_korr = 1;                        

if(sct_bit==0)
{
TCCR0 |= (1 << CS02); // запускаем таймер (31.250 KHz)
//записываем в эл.массива
RC5_buffer [sct_bit] = !(PINC&(1 << PORTC.2));
sct_bit++; // +1 к счётчику принятых битов
centre = 1;          
}
else
{
// Проверка короткого промежутка
if ((Timer > TminK)&&(Timer < TmaxK))
{
if (centre)
{
centre = 0;
not_korr = 0;
}
else
{
centre = 1;
RC5_buffer [sct_bit] = !(PINC&(1 << PORTC.2));
sct_bit++;
not_korr = 0;
}
}
// проверка длинного промежутка
if ((Timer > Tmin)&&(Timer < Tmax))
{
RC5_buffer [sct_bit] = !(PINC&(1 << PORTC.2));
sct_bit++;
not_korr = 0;
}

if (not_korr == 1)
{              // если не попали ни в один из промежутков то 
rc5_ti_stop(); // останавливаем таймер
rc5_cl_buf(); // очищаем буфер
}
if (sct_bit == 14)
{              // если бит последний то
rc5_ti_stop(); // останавливаем таймер

// Формируем код команды
command = (RC5_buffer [8] << 5)|(RC5_buffer [9] << 4)|
(RC5_buffer [10] << 3 )|(RC5_buffer [11] << 2)|
(RC5_buffer [12] << 1)|RC5_buffer [13];

// Выводим данные на дисплей  
display1 = command%10; // преобразование для 1 цифры
command = command/10; // преобразование кода команды
display2 = command%10; // преобразование для 2 цифры
}
GICR |= (1 << INT0); // разрешаем прерывания по входу INT0
GIFR |= (1 << INTF0); // сбрасываем флаг прерывания по входу INT0                                                                        
}   
}

void main(void)
{
DDRB = 0xFF; // выход
PORTB = 0x00;
DDRC |= (1 << PORTC.1)|(1 << PORTC.0); // выход
DDRC &= ~(1 << PORTC.2);  // вход ИК
PORTC = 0x00;

TIMSK |= (1 << TOIE0); // разрешение прерывания по таймеру0
TIMSK |= (1 << TOIE1); // разрешение прерывания по таймеру1
TCCR1B |= (1 << CS10); // без предделителя

GICR |= (1 << INT0); // разрешаем прерывания по входу INT0
MCUCR |= (1 << ISC00); // прерывание по любому фронту
GIFR |= (1 << INTF0); // сбрасываем флаг прерывания

#asm  //разрешаем прерывания
sei
#endasm

while(1)
 { 
 } 
};

При повторном нажатии на одну и ту же кнопку выводится разные цифры, либо высвечивается 0.

Как это исправить?

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

Робот

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

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