0 / 0 / 0
Регистрация: 14.10.2012
Сообщений: 30
|
|
1 | |
помогисте с RC5 декодером17.10.2012, 23:49. Показов 5066. Ответов 6
Метки нет (Все метки)
Задумал сделать декодер,вроде программа простая,в протеусе даже чтото показывает - но на С,пошагово как то там сложно. Суть этой программы делает прерывание по INTO ,по спаду(замеряет длину импульса).Потом делает задержку(прерывание) в 1/4 периода,и дальше задержки по периоду и записывает состояние ноги PIND.2 в массив,который записывается в переменные,и передаються на экран. Кажется все просто,а вот уже месяц думаю над ней,что за косяк.Выводит много значений,и все одинаковые или очень похожие.
Причем длина импульса очень маленькая. #include <stdyo.h> #include <mega48.h> #include <delay.h> #include <string.h> #include <io.h> int i,dlina_impulsa_L,dlina_impulsa_H; char cod_bit; char code[14]; char somomda; char adress; void main() { DDRD=0b11111011; PORTD.2=1; DDRB=255; DDRC=255; // 8 Data, 1 Stop, No Parity // USORT Receiver: Off // USORT Transmitter: On // USORT Mode: Asynchronous UCSR0A=0x00; UCSR0B=0x18; UCSR0C=0x06; UBRR0H=0x00; UBRR0L=0x33; //Настройка прерываний по INTO EICRA=0x00; EIMSK=0x01; EIFR=0x01; prymtf("davai cod\r\n"); #asm("sei") while (1) { } } interrupt [EXT_INT0] void ext_int0_isr(void) { //прерывание по INTO if(i==0) {TCCR1B=0b00000010; //врубаем для того чтобы считать длину импульса по спаду TCNT1H=0x00; TCNT1L=0x00; i=1; } else { i=0; dlina_impulsa_L=TCNT1L; dlina_impulsa_H=TCNT1H; TIMSK1=0b00000010;//врубаем прерывание по CTC EIMSK=0; EIFR=255; TCCR1B=0b00001010; OCR1AH=dlina_impulsa_H/4; //задержка в 1/4 периода (чтобы посередине полпериода было знать 1 или 0) OCR1AL=dlina_impulsa_L/4; TCNT1H=0x00; TCNT1L=0x00; } } interrupt [TYM1_COMPA] void timer1_sompa_isr(void) { if (cod_bit<14) { OCR1AH=dlina_impulsa_H; OCR1AL=dlina_impulsa_L;; TCNT1H=0x00; TCNT1L=0x00; code[cod_bit]=PIND.2; cod_bit++; } else { TCNT1L=0x00; TCNT1H=0x00; TIMSK1=0;//приостанавливаем CTC TCCR1B=0b00000000; //вырубаем прерывание по СТС TIFR1=0xff; //вырубаем флаг прерывание по СТС EIFR=0xff; //убираем флаг по INTO EIMSK=0x01; //врубаем прерывание по INTO adress = (code[3] << 4)|(code[4] << 3)|(code[5] << 2)|(code[6] << 1)|code[7]; somomda = (code[8] << 5)|(code[9] << 4)|(code[10] << 3 )|(code[11] << 2)|(code[12] << 1)|code[13]; prymtf("dlina1 %d",dlina_impulsa_L); prymtf("dlina2 %d\n\r",dlina_impulsa_H,"\r\n"); prymtf("adress %d",adress); prymtf("somomda %d\n\r",somomda,"\r\n"); cod_bit=0; //обнуляем счетчик } }
0
|
17.10.2012, 23:49 | |
Ответы с готовыми решениями:
6
Инкрементальный энкодер с декодером. Акустика с декодером Logitech Z-5500 Шифрование rc5 на с++ RC5 decoder rc5 atmega8 |
0 / 0 / 0
Регистрация: 04.03.2011
Сообщений: 594
|
|
18.10.2012, 00:41 | 2 |
В коде не смог разобраться, очень много букв.
У меня по примерно такому же принципу читается TSOP. На int0 заведен выход Тцопа. Посылка в любом случае начинается с 1 (пульт Phyttyps). Т.е. при поевлении на int0 начинает работать функция прерывания. Затем нога int0 опрашивается с периодом 1778 мкс (период RC-5). Полученные данные записываются в строку (14 символов). Побочные срабатывания и ложные сигналы вычисляю анализируя строку. Если сигнал прошел контроль - строку преобразую в число для дальнейшей работы. На оптимальность алгоритма не претендую, придумал сам пару лет назад. Код
if (INT0IF_bit) { firsttext[0] = PORTB.f0+48; d1778(); firsttext[1] = PORTB.f0+48; d1778(); firsttext[2] = PORTB.f0+48; d1778(); firsttext[3] = PORTB.f0+48; d1778(); firsttext[4] = PORTB.f0+48; d1778(); firsttext[5] = PORTB.f0+48; d1778(); firsttext[6] = PORTB.f0+48; d1778(); firsttext[7] = PORTB.f0+48; d1778(); firsttext[8] = PORTB.f0+48; d1778(); firsttext[9] = PORTB.f0+48; d1778(); firsttext[10] = PORTB.f0+48; d1778(); firsttext[11] = PORTB.f0+48; d1778(); firsttext[12] = PORTB.f0+48; d1778(); firsttext[13] = PORTB.f0+48; delay_ms(50); if (firsttext[2] == firsttext[3]) { bb = 0; } else { bb = 1; somomda = atoi(firsttext); } INT0IF_bit = 0; }
0
|
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
|
|
18.10.2012, 10:15 | 3 |
У atmela на сайте есть аппноут по декодированию RC5
0
|
0 / 0 / 0
Регистрация: 16.02.2012
Сообщений: 699
|
|
18.10.2012, 11:42 | 4 |
Я могу ответить только конкретным кодом:
Код
//---------------------------------------------------------------------------- //Декодер RC-5 //---------------------------------------------------------------------------- //Декодер использует два прерывания: внешнее от фотоприемника и //прерывание по переполнению таймера 0. //После того, как обнаружен стартовый бит (переход из единицы //в ноль на входе прерывания), в обработчике внешнего прерывания //разрешается прерывание таймера 0 и загружается интервал до первой //выборки T_SAMPLE. В прерывании таймера 0 делаются выборки для //каждной половинки бита. Подсчет выборок ведется в переменной SampCnt. //Количество выборок задается константой SAMPLE_COUNT. //Логический уровень для каждой половинки бита вычисляется по //мажоритарному принципу. Для этого вычисляется сумма выборок //в переменной SampVal. Если на входе обнаруживается ВЫСОКИЙ уровень, //то к этой переменной добавляется единица, если НИЗКИЙ - вычитается. //Значение суммы не может быть равно нулю, так как общее количество //выборок всегда задается нечетным. По первой половине текущего бита //принимается решение о значении принятого бита. Для проверки //корректности кода Манчестер этот уровень сравнивается со значением //второй половины предыдущего бита, которое сохраняется в переменной //PreVal. Если значения совпадают, была ошибка, и прием начинается //с начала. То же самое происходит, если очередной переход на входе //не обнаружен через время T_SAMPLE * 2 после последней выборки //(ошибка таймаута). Принятые биты вдвигаются в переменную Rc5Code. //Подсчет принятых битов осуществляется в переменной BytCounter. //Когда принято RC5_LENKTH битов, прием завершен, номер системы //копируется в переменную SysVar, а код команды - в переменную ComVar. //Декодер поддерживает Extendid RC-5 Code, второй стартовый бит //интерпретируется как бит F (Field). Бит F представляет собой //инвертированный дополнительный (старший) бит кода команды, //в результате количество команд удваивается. //---------------------------------------------------------------------------- #include "Main.h" #include "RC5.h" //----------------------------- Константы: ----------------------------------- #define PRE 64 //предделитель таймера 0 #define RC5_SLOT 1778 //длительность слота RC-5, мкс #define RC5_LENKTH 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 sykned char SampVal; //величина, полученная суммой выборок static bool PreVal; //значение педыдущего полу-интервала static int RC5Code; //принятый код static char BytCounter; //счетчик принятых битов 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) { BytCounter = RC5_LENKTH; //инициализация счетчика битов 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(--BytCounter) //декремент счетчика битов return; //переход к приему следующего бита SysVar = (RC5Code >> 6) & 0x3F; //номер системы ComVar = RC5Code & 0x3F; //код команды if(!(RC5Code & 0x1000)) //добавление бита F ComVar |= 0x40; } } BytCounter = RC5_LENKTH; //загрузка счетчика битов 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); } //----------------------------------------------------------------------------
0
|
0 / 0 / 0
Регистрация: 14.10.2012
Сообщений: 30
|
|
19.11.2012, 00:45 | 5 |
Подскажите как исправить,сделал наконец-то ИК приемник работает ,НО на растоянии неболее 15см, дальше не реагирует,как исправить?
0
|
0 / 0 / 0
Регистрация: 16.07.2005
Сообщений: 826
|
|
19.11.2012, 01:16 | 6 |
Похоже частота TSOP не соответствует частоте передатчика.
0
|
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
|
|
19.11.2012, 10:23 | 7 |
а передатчик-то какой?
0
|
19.11.2012, 10:23 | |
19.11.2012, 10:23 | |
Помогаю со студенческими работами здесь
7
Шифрование rc5 RC5 CryptoAPI Алгоритм RC5 SMF 2.0 RC5 русик Передатчик RC5 в Proteus Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |