Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача информации с помощью ИК
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
eugmai86
Доброго времени суток.
Пытаюсь передавать 4 команды от одного контроллера к другому. МК 1 Трансивер Tiny 13, приемник tiny2313. Передать одну команду(внешнее прерывание в тини) не проблема, все работает. А вот никак не могу разобраться с алгоритмом и его реализацией для нескольких команд.
Для передатчика использую следующий алгоритм:
Если нажата кнопка 1
-передаю 5 раз 20 импульсов с паузой 260мкс после каждого импульса
Если нажата кнопка 2
-передаю 10 раз 20 импульсов с паузой 260мкс после каждого импульса
...
Если нажата кнопка 4
-передаю 20 раз 20 импульсов с паузой 260мкс после каждого импульса


Приемник должен гонять таймер с частотой самого длинного импульса, в моем случае 26мкс(время 1 импульса)*20(кол-во пульсаций)*20(раз передается импульс)+260мкс(задержка после каждой пачки импульсов)*20(пачек импульсов)=15,6 мс. Что равно 64 Гц (если я не ошибаюсь).

В момент когда нажата кнопка на передатчике, на приемнике срабатывает внешнее прерывание

interrupt [EXT_INT0] void ext_int0_isr(void)
{
TCNT0=0xF0; //запускаем таймер 64 Гц, время самого длинного импульса
TCCR0B=0x04;

}

И в этот момент мне нужно посчитать сколько же было послано пачек 5,10, 15, или 20. Как не знаю. Застрял. Помогите. Может быть есть стандартные библиотеки для МК на этот случай.
Пишу в CVAVR
kovigor
Цитата(eugmai86 @ Mar 20 2011, 18:15) *
И в этот момент мне нужно посчитать сколько же было послано пачек 5,10, 15, или 20. Как не знаю. Застрял. Помогите. Может быть есть стандартные библиотеки для МК на этот случай.
Пишу в CVAVR


Очень просто. Цифровой автомат.
Состояние S0: приемник ждет прерывания. При получении прерывания приемник переходит в S1
Состояние S1: приемник принимает импульсы (первые пять). При получении первых 5-ти импульсов, если через заданное время больше импульсов принято не было, то приемник считает, что это команда из пяти импульсов и переходит в S0. Если же импульсы были, то приемник переходит в S2.
Состояние S2: приемник принимает импульсы (очередные пять). При получении очередных 5-ти импульсов, если через заданное время больше импульсов принято не было, то приемник считает, что это команда из десяти импульсов и переходит в S0. Если же импульсы были, то приемник переходит в S3. И так далее.

Но так делать не надо. Почему бы просто не передавать команды по UART, защищая каждую команду (например, такую: "CMD1", "CMD2", ...) байтом CRC8 (или словом CRC16, или CRC32) ? Просто, стандартно, длина команды всегда постоянна, легко добавлять новые команды, реализаций CRC готовых масса ...
eugmai86
Дело в том, что у тини 13 нет UART

Т.е. если есть внешнее прерывание вызывается ф-ция обработки, она же считает сколько было изменений на ноге контроллера.
А как правильно таймер запустить чтоб он стартовал с начала сигнала и останавливался по переполнению, а не стартовал при каждом прерывании как у меня. Только не отправляйте в даташит, читал много раз и внимательно. Просто некому один раз в живую объяснить. Спасибо
char tick=0;
interrupt [EXT_INT0] void ext_int0_isr(void)
{
TCNT0=0xF0; //запускаем таймер 64 Гц, время самого длинного импульса
TCCR0B=0x04;
tick++;
}
void tick_calc (void)
{
if (0<<=5)
{
//do smth1
TCNT0=0x00; //останавливаю таймер
TCCR0B=0x00;
tick=0;//сбрасываю тики
}
...
if (15<tick<=20)
{
//do smth4
TCNT0=0x00; //останавливаю таймер
TCCR0B=0x00;
tick=0;
}
}
SKov
Цитата(eugmai86 @ Mar 20 2011, 18:15) *
-передаю 5 раз 20 импульсов с паузой 260мкс после каждого импульса
...
26мкс(время 1 импульса)

Уточните, плз, чем вы принимаете такой затейливый ИК-сигнал.
eugmai86
На Tiny2313 включено внешнее прерывание на INT0, на эту ногу повешен выход TSOP4838
Xecutor
ИК-сигнал не очень стабильная среда передачи информации. Вы уверенны, что вам не требуется подтверждения приёма команд со стороны приёмника?
Ну и может стоит обратить внимание на "старые" проверенные протоколы для ПДУ бытовой техники или расширить их введя избыточность данных.
eugmai86
Нажмите для просмотра прикрепленного файлаНа данном этапе обратная связь не требуется, смотрел образцы для NEC и Sony(см приложение). Так и не смог разобраться. Опыта маловато.
SKov
Цитата(eugmai86 @ Mar 20 2011, 19:49) *
На Tiny2313 включено внешнее прерывание на INT0, на эту ногу повешен выход TSOP4838


Тогда у вас, возможно, не очень четко написано в посте. Надо передавать импульсы 26мкс с интервалом 26мкс и передавать не менее десяти импульсов (лучше 20 импульсов). А вот уже после такой пачки можно делать перерыв. Или не делать. У вас так и сделано?
eugmai86
Нажмите для просмотра прикрепленного файлаСмотрите в приложении. Или часть кода тут:
#define IR_LED PORTB.0
volatile bit button_pressed1, button_pressed2, button_pressed3, button_pressed4; //флаг
void press_key (void)
{ char i;
for(i=0;i<=19;i++)//пачка из 30 импульсов
{
delay_us(13);// почти меандр 38кГц
IR_LED=1;
delay_us(13);
IR_LED=0;
};
delay_us(260);//та самая пауза,
};
Дальше в main:
if (PINB.1 == 0 && button_pressed1 == 0) //Если нажата кнопка 1
{
char k;
for (k=0;k<5;k++)
{
press_key();
};
button_pressed1 = 1;

}
...
if (PINB.4 == 0 && button_pressed4 == 0) //Если нажата кнопка 4
{
char k;
for (k=0;k<20;k++)
{
press_key();
};
button_pressed4 = 1;

}
if (PINB.4 == 1) button_pressed4 = 0; //сбрасываем флаг

Получается я передаю 30 импульсов а за ними пауза.
kovigor
Цитата(eugmai86 @ Mar 20 2011, 22:35) *
Получается я передаю 30 импульсов а за ними пауза.


Я бы смотрел в сторону RC5. Все это уже давно разработано и испытано. А ваш метод никуда не годится. Один импульс пропал - и всей передаче крышка ...

http://digit-el.com/files/open/rc5/rc5.html

P.S. А передатчик UART элементарно реализуется чисто программно на любой из ножек любого из портов ...
SKov
Цитата(eugmai86 @ Mar 20 2011, 21:35) *
Получается я передаю 30 импульсов а за ними пауза.

Ну значит в этом месте все правильно. Только паузу между пачками лучше побольше раза в два-три.
Я бы посоветовал кодировать кнопки интервалами между пачками.
eugmai86
Так всеже как правильно таймер запустить чтоб он стартовал с начала сигнала и останавливался по переполнению, а не стартовал при каждом прерывании. Вопрос то по сути не сложный, недавно програмирую, мало что знаю поэтому и спрашиваю.
Нужно при появлении низкого уровня (внешнее прерывание) посчитать кол-во импульсов. Какие импульсы, их длины все написал, подскажите как. Я знаю что есть RC-5 RC-6 еще вагон протоколов, но ведь требуется передать 4 (четыре) команды а не 20.
SKov
Цитата(eugmai86 @ Mar 20 2011, 23:22) *
Так всеже как правильно таймер запустить чтоб он стартовал с начала сигнала и останавливался по переполнению, а не стартовал при каждом прерывании. Вопрос то по сути не сложный, недавно програмирую, мало что знаю поэтому и спрашиваю.
Нужно при появлении низкого уровня (внешнее прерывание) посчитать кол-во импульсов. Какие импульсы, их длины все написал, подскажите как. Я знаю что есть RC-5 RC-6 еще вагон протоколов, но ведь требуется передать 4 (четыре) команды а не 20.

Не морочьте себе голову с протоколами. В вашем описании немного сбивает с толку, что вы называете импульсами и короткие импульсы на выходе ИК-передатчика и сигналы на выходе ИК-приемника. У приемника на выходе уже имульсы, примерно совпадающие с длительностью пачки из 30коротких импульсов.
Теперь относительно измерения интервала времени между пачками. (Это я предполагаю, что вы вняли моему предложению кодировать кнопки интервалами между пачками.) При поступлении пачки у вас происходит прерывание. Вы должны в подпрограмме обработки перерывания проверить состояние таймера, который заполняется импульсами от основного ТГ контроллера (через прескалер, если он там есть - точно не помню). Тут времянку надо аккуратно посчитать, чтобы таймер не переполнялся при самом большом интервале меду пачками. Дальше, вы посмотрели на содержимое таймера и решили, какая кнопка нажата. После этого вы обнуляете таймер и выходите из прерывания. До прихода следующей пачки. Для пущей надежности окончательное решение о нажатой кнопке можно принимать, когда накопилось три (или пять) одинаковых решений относительно кнопки (я предполагаю, что пачек за время нажатия кнопки уйдет не менее 5-ти).
Как-то так. А с вашей программой вряд ли кто будет подробно разбираться. Ну, если у кого совсем много свободного времени. wink.gif
eugmai86
ясно, спасибо. тут еще порекомендовали попробовать без таймера. просто считать сколько прерывание случилось. разбираюсь. спасибо
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.