|
|
  |
ИК ПДУ, Как определить протокол ПДУ и считать данные |
|
|
|
May 18 2009, 12:49
|
Группа: Новичок
Сообщений: 3
Регистрация: 18-05-09
Из: Харьков
Пользователь №: 49 227

|
Электронщики и программисты поделитесь пожалуйста опытом получения кода от ПДУ. Написал и переделал уже 5 исходников на си и на асме, но не получаю в регистрах результата вобще ничего. Результат отсылаю в СОМ-порт, но туда ничего не отправляется. после нажатия кнопки пульта программа уходит неясно куда У меня есть алгоритм в котором после певого прерывания отсчитывают временные интервалы и изэтого прерывания МК и не выходит. В форуме не нашел темы про RC5
|
|
|
|
|
May 18 2009, 13:41
|

Участник

Группа: Свой
Сообщений: 63
Регистрация: 13-03-06
Из: Москва
Пользователь №: 15 204

|
Цитата(Farat @ May 18 2009, 15:49)  В форуме не нашел темы про RC5 А есть уверенность, что Ваш пульт выдает именно RC5 ? А так всё просто - осциллограф в левую руку и http://www.sbprojects.com/knowledge/ir/ir.htm в правую.
|
|
|
|
|
May 18 2009, 14:14
|
Местный
  
Группа: Свой
Сообщений: 342
Регистрация: 21-06-04
Пользователь №: 85

|
Цитата(Farat @ May 18 2009, 16:49)  Электронщики и программисты поделитесь пожалуйста опытом получения кода от ПДУ. Написал и переделал уже 5 исходников на си и на асме, но не получаю в регистрах результата вобще ничего. Результат отсылаю в СОМ-порт, но туда ничего не отправляется. после нажатия кнопки пульта программа уходит неясно куда  Позвольте Вам не поверить, Вы не написали и переделали 5 исходников, а просто попытались методом тыка оживить лежащие в инете исходники, не разобравшись в принципе, что же там происходит. Это путь хорош для сдачи лаб, но не для запуска изделия. Там в принципе вообще нечего делать. И даже неважно в каком формате что то передается. Для начала Вы должны записать все что приняли в память процессора, для чего считаете таймером задержки между перепадами фронта сигнала, и пишете эти цифры в память. Для начала сгенерируйте таймером процессора какой нибудь меандр, и заведите его обратно на вход, на котором осуществляется прием с пульта. И попробуйте словить свой собственный меандр. Как только вы получите вменяемые цифры пойманного меандра, считайте задачка решена.
|
|
|
|
|
May 19 2009, 15:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
вот тут мой вариант, который, как оказалось, расчудесно принимает и не-RC5 коды (только принятые значения не соответствуют документированным, но однозначное соответствие пульт-кнопка-код обеспечивается): http://arv.radioliga.com/downloads/html.rarпо ссылке архив html-документации, из которого должно быть все понятно ( это не исходник!)
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
May 20 2009, 11:03
|
Группа: Новичок
Сообщений: 3
Регистрация: 18-05-09
Из: Харьков
Пользователь №: 49 227

|
А для того чтобы посмотреть осциллографом сигнал ПДУ, нужно чтоб осциллограф был запоминающий, или можно и на аналоговом?
|
|
|
|
|
May 20 2009, 11:23
|

Участник

Группа: Свой
Сообщений: 63
Регистрация: 13-03-06
Из: Москва
Пользователь №: 15 204

|
Цитата(Farat @ May 20 2009, 14:03)  А для того чтобы посмотреть осциллографом сигнал ПДУ, нужно чтоб осциллограф был запоминающий, или можно и на аналоговом? С цифровым удобнее, безусловно. Но и обычный пойдет - нужно-то только понять, в каком из стандартов работает пульт. А дальше по букварю всё (одну из ссылок я давал выше).
|
|
|
|
|
May 20 2009, 13:44
|
Частый гость
 
Группа: Свой
Сообщений: 92
Регистрация: 8-03-05
Пользователь №: 3 160

|
Запишите сигнал аудиокартой, у меня audigy2 все прекрасно видно. А это мой вариант приемника.
|
|
|
|
|
May 21 2009, 22:05
|

Местный
  
Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986

|
Сейчас я использую такой декодер RC-5 на Си для AVR: Код //----------------------------------------------------------------------------
//Декодер RC-5
//----------------------------------------------------------------------------
//Декодер использует два прерывания: внешнее от фотоприемника и от таймера 0. //После того, как обнаружен стартовый бит (переход из единицы //в ноль на входе прерывания), в обработчике внешнего прерывания //разрешается прерывание таймера 0 и загружается интервал до первой //выборки T_SAMPLE. В прерывании таймера 0 делаются выборки для //каждной половинки бита. Подсчет выборок ведется в переменной SampCnt. //Количество выборок задается константой SAMPLE_COUNT. //Логический уровень для каждой половинки бита вычисляется по //мажоритарному принципу. Для этого вычисляется сумма выборок //в переменной SampVal. Если на входе обнаруживается ВЫСОКИЙ уровень, //то к этой переменной добавляется единица, если НИЗКИЙ - вычитается. //Значение суммы не может быть равно нулю, так как общее количество //выборок всегда задается нечетным. По первой половине текущего бита //принимается решение о значении принятого бита. Для проверки //корректности кода Манчестер этот уровень сравнивается со значением //второй половины предыдущего бита, которое сохраняется в переменной //PreVal. Если значения совпадают, была ошибка, и прием начинается //с начала. То же самое происходит, если очередной переход на входе //не обнаружен через время T_SAMPLE * 2 после последней выборки //(ошибка таймаута). Принятые биты вдвигаются в переменную Rc5Code. //Подсчет принятых битов осуществляется в переменной BitCounter. //Когда принято RC5_LENGTH битов, прием завершен, номер системы //копируется в переменную SysVar, а код команды - в переменную ComVar.
//----------------------------------------------------------------------------
#include "Main.h" #include "RC5.h"
//----------------------------- Константы: -----------------------------------
#define PRE 64 //предделитель таймера 0 #define RC5_SLOT 1778 //длительность слота RC-5, мкс #define RC5_LENGTH 14 //количество принимаемых битов #define SAMPLE_COUNT 3 //количество выборок (должно быть нечетным)
#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; //код команды } } 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); }
//----------------------------------------------------------------------------
--------------------
|
|
|
|
|
May 22 2009, 05:52
|

Местный
  
Группа: Участник
Сообщений: 239
Регистрация: 30-10-07
Из: Санкт-Петербург
Пользователь №: 31 866

|
"Товарищи ученые! У меня в подполе который год происходит подземный стук. Объясните, пожалуйста, как он происходит?" (с) классики
Автор задает довольно отстраненный и уклончивый вопрос на тему "у меня тут нечто не работает" - а ему дают ворох уклончивых ответов на тему "а у нас работает". Может на этом пути и можно чего-то добиться, но я преисполнен ядовитого скептицизма.
И кстати, конечно очень важно указание, что написано именно 5 исходников, из которых некоторые на си, а некоторые на асме. Теперь, конечно, всем все стало понятно и каждый сможет точно сказать, в чем именно проблема. Вот это я называю "детальное описание неполадки"... Да... ;-)
Действуйте так:
1) Введите в гугле WinScope. Найдете сразу программу WinScope 2.51 - осциллограф на звуковухе. (если нет цифрового осциллографа, это вполне сойдет)
2) Подключите ваш фотодатчик (если вы используете датчик на конкретную частоту несущую)и проверьте, видно чего-нибудь интересное, или нет. Несмотря на входные кондеры в звуковухе, сигнал, при его наличии, будет настолько ясным, что вы его сразу узнаете.
3) Если с вашим датчиком не получилось, подключите фотодиод или фототранзистор (убедившись что вы представляете как их вообще подключать) и проверьте вновь наличие сигнала.
4) Помедитировав над осциллограммами (и гуглом) убедитесь, RC5 это или нечто другое.
5) Если вы проделаете эти упражнения, у вас уже накопится критический уровень понимания для того, чтобы либо разобраться самому, либо сформулировать вопрос конкретно, с пониманием того, что же не работает на самом деле. ;-)))
Сообщение отредактировал RodionGork - May 22 2009, 05:57
|
|
|
|
|
May 22 2009, 07:55
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
А когда-то давно вот такой приемник RC5 сотворил. Настройка периферии не показана. Потом этот код (правда уже вынесенный из обработчиков прерываний) скрестил с AVR-CDC (на меге8) - работает отлично... Код //TSOP подключен к INT0 #include <mega16.h> #include <stdio.h>
//МАКРОСЫ #define RC5_SIZE 14 #define PIN_RC 2 /*приемный пин (номер в порту)*/ #define RC5_BIT !(PORTD&(1<<PIN_RC)) //Временные пределы #define T_MIN 20 /*длинный промежуток (корректируются в соответствии с частотой*/ #define T_MAX 34 /* тактирования таймера Т0)*/ #define T_MIN_SH 11 /*короткий промежуток*/ #define T_MAX_SH 17
//Глобальные переменные (используются в обработчиках и основном цикле, либо для скорости) unsigned char sct_bit;//Счетчик битов RC5 unsigned char rc5_buffer[RC5_SIZE];//буфер RC5 unsigned char fl_recieve_rc5; //флаг события приема //структура принятого кода struct rc5_str{ unsigned char startbit2; unsigned char trigger; unsigned char device; unsigned char command; }rc5_code;
//--------------Обработчик прерывания по ИЗМЕНЕНИЮ уровня на int0------------------------// interrupt [EXT_INT0] void ext_int0_isr(void) { static unsigned char centre;//флаг центра unsigned char error=1; //выставляем флаг ошибки, сбросим в теле обработчика, если все ОК... unsigned char timer_rc5=TCNT0;//запоминаем значение счетчика TCNT0=0; switch (sct_bit){ case 0: TCCR0=0x05; //запускаем таймер (15.625 KHz) rc5_buffer[sct_bit]=RC5_BIT;//записываем в эл.массива sct_bit++; centre=1; break; default: if ((timer_rc5>T_MIN_SH)&&(timer_rc5<T_MAX_SH))//проверка кор. промежутка { if (centre){ centre=0; error=0; } else { centre=1; rc5_buffer[sct_bit]=RC5_BIT; sct_bit++; error=0; } } if ((timer_rc5>T_MIN)&&(timer_rc5<T_MAX)){//проверка длинного промежутка rc5_buffer [sct_bit]=RC5_BIT; sct_bit++; error=0; } if (error){// если не попали ни в один из промежутков то char i; GICR|=0x00; //запрещаем прерывания по изм. по входу TCCR0=0x00; //(разрешим в обр. прер. по переполнению счетчика) TCNT0=0; sct_bit=0; //очищаем буффер for (i=0;i<RC5_SIZE;i++)rc5_buffer[i]=0; } if (sct_bit==14){// если бит последний то: TCCR0 = 0x00; //останавливаем таймер TCNT0=0; sct_bit = 0; //формируем из массива соответствующие коды rc5_code.startbit2=rc5_buffer[1]; rc5_code.trigger=rc5_buffer[2]; rc5_code.device=(rc5_buffer[3]<<4)|(rc5_buffer[4]<<3)|(rc5_buffer[5]<<2)|(rc5_buffer[6]<<1)|rc5_buffer[7]; rc5_code.command=(rc5_buffer[8]<<5)|(rc5_buffer[9]<<4)|(rc5_buffer[10]<<3)|(rc5_buffer[11]<<2)|(rc5_buffer[12]<<1)|rc5_buffer[13]; fl_recieve_rc5=1; //установили флаг приема GIFR=0x40; // сбрасываем флаг прерывания по входу INT0 } } } //=============================================================//
//------------ Обработчик прерывания по переполнению Т0 (таймаут)-----------------------// interrupt [TIM0_OVF] void timer0_ovf_isr(void) { unsigned char i = 0; GICR|=0x00; TCCR0=0x00; //останавливаем таймер TCNT0=0; sct_bit=0; //очищаем буффер (его очищать необязательно) for (i=0;i<RC5_SIZE;i++) rc5_buffer[i]=0; GICR|=0x40; //разрешаем прерывания по входу GIFR=0x40; } //=============================================================//
... //пример использования: //отправляем по UART данные в случае приема кода if (fl_recieve_rc5){ printf ("StartBit2 %d Trigger %d Device %d Command %d",rc5_code.startbit2, rc5_code.trigger, rc5_code.device, rc5_code.command); fl_recieve_rc5=0;} ... P.S. Код чуть подправил для красоты, поэтому могут остаться артефакты...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|