Главная » Статьи » Swordfish |
Прием ИК сигнала протокола NEC
Вот и настал момент когда пришлось заняться приемом и декодировки ИК сигнала. После поисков по загашникам не обнаружил пультов (RC 5), зато нашел пульт от TV SHIVAKI (52 кнопки). По протоколу особо рассказывать не буду. Принцип прекрасно расписан здесь.. За основной алгоритм был выбран принцип декодировки с помощью таймера и порта B.0 настроенное на прерывание по спаду сигнала(статья), но так как протоколы NEC и RC5 разные, пришлось переделывать алгоритм декодировки сигнала(алгоритм захвата и измерения остался практически без изменений). Теперь немного про захват и декодирование. На рисунке (скрин с протеуса) изображен фрагмент кодовой посылки и байты повтора (IR). /IR входной (инверсный сигнал) поступающий на PORTB.0 и INT - индикация входа в программу прерывания. Фрагмент кода прерывания: Code Public Interrupt On_INT() SaveFSR0 = FSR0 SaveFSR1 = FSR1 SavePROD = PRODRegister High(PORTB.4) //---------------------------------------------- If TMR0IF=1 Then // если переполнение таймера TMR0IF=0 // сбросили флаг IR.EndS=1 // выставили флаг признака конца посылки IR.IntC=1 // разрешили инкриминирование счетчика переполнений (для детектирования битов повтора или конца посылки) End If //----------------------------------------------- If B0IF=1 Then // если произошел спад сигнала по B.0 B0IF=0 // сбросили флаг TMR0ON=0 // стопронули таймер TeMp.Byte0=TMR0l // перенесли 16 битное значение таймера в переменную TEMP TeMp.Byte1=TMR0h tmr0h=0 // сбросили в 0 значение таймера tmr0l=0 IR.Det=1 // выставили флаг признака детектирования сигнала IR.EndS=0 // сбросили флаг конца посылки ' End Select TMR0ON=1 // запустили таймер End If //----------------------------------------------- Low(PORTB.4) // тест входа в прерывания //----------------------------------------------- FSR0 = SaveFSR0 FSR1 = SaveFSR1 PRODRegister = SavePROD End Interrupt При переходу из 1 в 0 происходит прерывание, значение которое успел насчитать TMR0 переносится в переменную TEMP (обрабатываются в основной программе), TMR0 сбрасывается в 0 и запускается по новой. Если происходит прерывание по переполнению TMR0 (фрагмент рисунка между кодовой посылкой и битами повтора), сбрасывается флаг TMR0IF и устанавливаются флаги признака переполнения таймера (обрабатываются в основной программе). Переменные необходимые для декодирования и их назначение: Code // страховочные значения системных регистров при прерывании Public Dim PRODRegister As PRODL.AsWord, SaveFSR0, SaveFSR1, SavePROD As Word // флаги для PortB0( прерывание и включение) Public Dim B0IF As INTCON.1, // b0 int flag B0IE As INTCON.4 // enable int b0 // флаги для PortB1( прерывание и включение) Public Dim B1IF As INTCON3.0, // b1 int flag B1IE As INTCON3.3 // enable int Public Dim TMR0IE As INTCON1.5, // TMR0 флаг включения прерывания TMR0IF As INTCON1.2, // TMR0 флаг срабатывания прерывания TMR0ON As T0CON.7 // TMR0 Приращение вкл Public Dim TeMp As Word // временная для таймера Public Dim Start_Flag As Boolean // Флаг разрешения работы Public Structure TIR // структурируем Stat As Byte // байт флагов состояния Sta As Stat.bit0 // флаг обнаружения стартового импульса EndS As Stat.bit1 // флаг прерывания по переполнению таймера Err As Stat.bit2 // флаг ошибки приема Ok As Stat.bit3 // флаг удачой проверки сравнения кода Rep As Stat.bit4 // флаг повтора Det As Stat.bit5 // флаг прерывания по приему ИК сигнала IntC As Stat.bit6 // флаг запрета повторного инкременирования IntN Adr As Word // адрес комманды приема H-нормальный, L- инверсия Com As Word // код комманды H-нормальный, L- инверсия IntN As Byte // пер. кол-ва переполнения таймера Res(50) As Word BitN As Byte // количество принятых бит кода End Structure Public Dim IR As TIR // объявляем структуру Самый первых вопрос который возникает. Что значят строчки: Public Structure TIR // структурируем End Structure Public Dim IR As TIR // объявляем структуру Это так называемое структурирование (применяется в VB6 для упрощения читаемости кода) каждая сточку следующую после Public Structure TIR можно заменить на Public Dim IR_Stat As Byte например, и т.д. Теперь кусок кода который детектирует принятые значения таймера (TEMP) и флагов состояний. Code IR.Com=0 // сбросили флаги и значения (начальные) IR.Adr=0 IR.IntN=0 CLR: // сбросили флаги и значения (для приема новой команды) IR.Stat=0 IR.BitN=0 loop: // основной цикл If IR.EndS=1 And IR.IntC=1 Then // если произошло прерывание и зафиксирован признак конца пакета Inc(IR.IntN) If IR.IntN=5 Then // если произошло больше 4 прерываний по переполнению таймера, то нет сигнала. IR.Com=0 // сбросили все переменные в 0 IR.Adr=0 IR.Stat=0 IR.BitN=0 IR.IntN=4 Low(PORTB.3) // сбросили индикацию повтора End If IR.IntC=0 // сброс счеткика переполнения таймера End If // ---- If IR.Det=1 Then IR.IntN=0 If IR.Sta=0 And TeMp>$8400 And TeMp<$8450 Then // детектируем стартовый импульс IR.Sta=1 // если он, выставили флаг End If If IR.Sta=1 And TeMp>$15d0 And TeMp<$1640 Then // детектируем "1" IR.Com.0=1 If IR.BitN<31 Then IR.Adr= IR.Adr<<1 IR.Adr.bit0=IR.Com.bit15 IR.Com= IR.Com<<1 End If Inc(IR.BitN) End If If IR.Sta=1 And TeMp>$0Ac0 And TeMp<$0B30 Then // детектируем "0" IR.Com.0=0 If IR.BitN<31 Then IR.Adr= IR.Adr<<1 IR.Adr.bit0=IR.Com.bit15 IR.Com= IR.Com<<1 End If Inc(IR.BitN) End If IR.Det=0 End If // --- If IR.Ok=1 And IR.EndS=1 And IR.IntC<4 And TeMp>$6d70 And TeMp<$6ff0 Then // если обнаружен бит повтора, код прошел проверку и не было переполнения по времени IR.Rep=1 // сбросили лишнее IR.Sta=0 IR.EndS=0 High(PORTB.3) // выставляем бит повтора End If If IR.EndS=1 And IR.BitN<>32 Then // если не совпала длинна, а уже произошло прерывание по переполнению IR.Com=0 // сбросили все переменные в 0 IR.Adr=0 IR.Stat=0 IR.BitN=0 IR.IntN=4 Low(PORTB.3) End If If IR.EndS=1 And IR.Sta=1 And IR.BitN=32 And IR.Ok=0 Then // если произошло прерывание, был стартовый сигнал, 32 бита приняли If IR.Adr.byte1=Not IR.Adr.byte0 And IR.Com.byte1=Not IR.Com.byte0 Then // проверяем что приняли IR.Ok=1 // если все совпало, значит код верен. Флаг правильности установили IR.Sta=0 IR.EndS=0 USART.Write ("Adress :",BinToStr(IR.Adr.byte1,8)," ",BinToStr(IR.Adr.byte0,8),13) // выплюнули код в USART USART.Write ("Command :",BinToStr(IR.Com.byte1,8)," ",BinToStr(IR.Com.byte0,8),13,13) Else // если не прошел проверку IR.Com=0 // сбросили все переменные в 0 IR.Adr=0 IR.Stat=0 IR.BitN=0 IR.IntN=4 Low(PORTB.3) End If End If GoTo loop основной блок выполнен по принципу If .. Then .. Else .. End if. То есть постоянно проверяются состояние флагов и значений и в зависимости от этого происходят действия. 1. Ловим стартовый бит 9+4.5ms. Поймали ??? выставили флаг начала приема 2. Если поймали стартовый бит и есть новый бит равный 1 или 0 и кол-во принятых бит меньше 31, то смещаем в право 16 битные регистры адреса IR.Adr и комманд IR.Com и заносим в IR.Com.bit0 принятый бит IR.Com.0=0 // заносим в IR.Com.bit.0 0 или 1 If IR.BitN<31 Then // если меньше 31 бита принято, то смещение данных IR.Adr= IR.Adr<<1 IR.Adr.bit0=IR.Com.bit15 IR.Com= IR.Com<<1 End If Inc(IR.BitN) // если больше 31 то просто прибавили 1 к счетчику бит 3. После приема 32 бит данных происходит прерывание по переполнению таймера(выставляются флаги окончания приема и переполнения таймера) If IR.EndS=1 And IR.IntC=1 Then // если произошло прерывание и зафиксирован признак конца пакета Inc(IR.IntN) If IR.IntN=5 Then // если произошло больше 4 прерываний по переполнению таймера, то нет сигнала. IR.Com=0 // сбросили все переменные в 0 IR.Adr=0 IR.Stat=0 IR.BitN=0 IR.IntN=4 Low(PORTB.3) // сбросили индикацию повтора End If IR.IntC=0 // сброс счеткика переполнения таймера End If 4. Проверяем флаги: произошло прерывание, был стартовый сигнал, 32 бита приняли ? Значит можно приступать к проверки кода. Здесь NEC интересно поступил. В 16 битах адреса (так же и комманд) нужно сравнить старший и младший бит. Если они равны, значит код верен (IR.Adr.byte1=Not IR.Adr.byte0 и IR.Com.byte1=Not IR.Com.byte0). Выставляем бит правильности принятого кода (IR.Ok=1) 5. Далее ловим бит повтора, и если он обнаружен выставляем флаг повтора (IR.Rep=1). 6. Если кодовая посылка прерывается (или биты повтора) то через 5 прерываний будет сброшен флаг повтора, остальные переменные, данные и программа будет ждать прихода нового стартового бита. Схема и проэкт а Протеусе с COF(позволяет производить пошаговую отладку в Протеусе) файлами прикладываю в Архиве. Там же приложенная программа имитация пульта ИК(Работает PORTB.0). Фотки и Видео макетки выложу попозже. Всем успехов и с наступающим Новым Годом !!!!! С уважением Алексей (DAlexV) | |
Просмотров: 16334 | Комментарии: 6 | | |
Всего комментариев: 6 | |||||||
| |||||||