В этой статье рассмотрена программа для самодельного ИК-приемника сигналов дистанционного управления на контроллере PIC12F629. Если вы измените аппаратную часть (например, будете использовать другой порядок ног, повесите внешний генератор), то программу так же нужно будет переделать.
Представленная программа является простейшей, она не проверяет соответствие принимаемых данных манчестерскому алгоритму, а для организации задержек использует пустые циклы (с командой nop).
Программа реализует следующие функции:
1) Прием кода RC-5 и запись его в 2 байта:
MBC — 7,6 биты — стартовые; 5 — управляющий бит; 4…0 — биты номера системы
LBC — 5…0 биты — номер команды; 7,6 биты — не используются
2) В рабочей части программы реализуется управление четырьмя светодиодами от четырёх кнопок пульта. Изменяя в прошивке соответствующие кнопкам коды команд, а также номер системы, можно привязать к нашему приёмнику любые 4 кнопки от любого пульта RC-5. Мы обозначим кнопки просто как 1, 2, 3, 4. Если нажать кнопку 1, то загорается первый светодиод, если кнопку 2, то второй светодиод, если кнопку 3 — третий и если кнопку 4 — четвертый
Прежде чем разбираться с самой программой, советую посмотреть описание протокола RC-5.
Основные идеи алгоритма:
1) Выход ILMS1836 — инвертированный, т.е. когда принимается "1" — на выходе фотоприемника "0" (низкий уровень), когда приема нет или принимается "0" — на выходе фотоприемника "1"(высокий уровень).
2) Стартовый бит манчестерским кодом передается как последовательность "01", но первый полубит ("0") мы не отличим от отсутствия сигнала, т.е. фактически прием начинается со второго полубита.
3) Если записывать все четные полубиты, начиная со второго, то мы восстановим исходную посылку.
4) В процессе работы программа считывает значение на входе контроллера каждые 1,78 мс и считает это значение — значением принятого бита. То есть мы принимаем только четные полубиты и считаем, что их значения соответствуют битам исходного сообщения.
5) Чтобы читать значения подальше от границы полубитов (где-то в середине), перед приемом первого полубита вводится пауза, примерно равная половине полубита.
Алгоритм:
![]() ![]() ![]() |
Итак, пусть в аппаратной части мы имеем:
входы: GP5 — вход ИК-приемника
выходы: GP0, GP1, GP2, GP4 — выходы на транзисторы управления светодиодами.
MCLR внешне подтянут к питанию; используется внутренний генератор.
Пусть мы ожидаем команды управления светом (номер системы 29).
list p = 12f629 __config 01FC4h ;*** Переменные ****************************************** CBLOCK 0x20 ; Начальный адрес блока пользовательской памяти MBC ; старший байт посылки (полбита - 889uS) LBC ; младший байт посылки Counter2 ; счетчики для пауз Counter1 Counter3 ENDC ;**** Константы / Адреса регистров ************************ T1 equ .212 ; задержка 1 T2 equ .2 TP equ .200 ; определяет задержку между приемом посылок Tn equ .50 ; начальная задержка (ближе к середине полубита) Sys equ .253 ; номер системы (29) + 2SB=1 + TB=1 CMD_1 equ .1 ; код команды 1 CMD_2 equ .2 ; код команды 2 CMD_3 equ .3 ; код команды 3 CMD_4 equ .4 ; код команды 4 Status equ 03h ; выбор банка GPIO equ 05h ; Регистр управления защелками порта Cmcon equ 19h ; Регистр Cmcon - компаратора TrisIO equ 05h ; Регистр выбора направления работы выводов порта INTCON equ 0Bh ; Регистр разрешения(1)/запрета(0) прерываний OSCCAL equ 10h ; Регистр хранения калибровочной константы F equ 1 ; Результат направить в регистр. ;********************************************************** ; Пусть у нас GP0 (1-й кр), GP1(2-й кр), GP2(жел), GP4(зел) - выходы на ; транзисторы управления светодиодов, GP5 - вход ИК-приемника ;********************************************************** org 0 ;*** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА ************************* ;*** Калибровка Генератора ******************************** start bsf Status,5 Call 3FFh ; Загрузить калибровочную константу в w movwf OSCCAL ;*** Установка направления работы GP5 - на вход, а GP4-GP0 - на выход bcf Status,5 ; перейти в банк 0 clrf GPIO ; инициализация защелок movlw .7 ; биты 0..2 поднять movwf Cmcon ; компаратор выключен, GP0, GP1, GP2 - цифровые вх/вых bsf Status,5 ; Перейти в 1-й банк movlw .40 ; Записать конфигурацию GPIO в аккумулятор (W) ; .40=00 101000 GP0,GP1,GP2,GP4 - выходы, остальные - входы movwf TrisIO ; Скопировать конфигурацию GPIO из W в регистр TrisIO bcf Status,5 ; перейти в банк 0 ;*** Сканирование наличия принятой информации ************* Scan btfss GPIO,5 ; если 5-й бит равен единице - данных нет, пропускаем call priem btfsc MBC,7 ; если start bit (7-й) в регистре MBC = 1, ; то была принята информация call rab_chast goto Scan ;*** ПРИЕМ ДАННЫХ ***************************************** priem clrf MBC clrf LBC ;********************************************************** movlw Tn movwf Counter3 wait_n nop decfsz Counter3,1 goto wait_n ;*** Первый полубит *************************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,7 call wait ;*** Третий полубит *************************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,6 call wait ;*** Пятый полубит **************************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,5 call wait ;*** Седьмой полубит ************************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,4 call wait ;*** Девятый полубит ************************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,3 call wait ;*** Одиннадцатый полубит ********************************* btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,2 call wait ;*** Тринадцатый полубит ********************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,1 call wait ;*** Пятнадцатый полубит ********************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf MBC,0 call wait ;*** Семнадцатый полубит ********************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf LBC,5 call wait ;*** Девятнадцатый полубит ******************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf LBC,4 call wait ;*** Двадцать первый полубит ****************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf LBC,3 call wait ;*** Двадцать третий полубит ****************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf LBC,2 call wait ;*** Двадцать пятый полубит ******************************* btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf LBC,1 call wait ;*** Двадцать седьмой полубит ***************************** btfss GPIO,5 ; если на входе GP5 единица - пропускаем bsf LBC,0 call wait return ;*** Пауза ************************************************ wait movlw T2 movwf Counter2 pause2 movlw T1 movwf Counter1 pause1 nop decfsz Counter1,1 goto pause1 decfsz Counter2,1 goto pause2 return ;********************************************************** ;*** Гашение всех светодиодов ***************************** gasim movlw b'11101000' addwf GPIO,1 return ;*** РАБОЧАЯ ЧАСТЬ **************************************** ;*** Проверка номера системы ****************************** rab_chast movlw Sys xorwf MBC,0 btfss Status,2 ; если бит 2 (Z) в регистре Status=1, то следующая ; инструкция не выполняется (номер = заданному) goto out ;*** Проверка команды 1 *********************************** movlw CMD_1 xorwf LBC,0 btfss Status,2 ; если Z=1, то следующ. инстр-я не выполн-ся goto com2 call gasim bsf GPIO, 0 ; зажечь первый светодиод goto out ;*** Проверка команды 2 *********************************** com2 movlw CMD_2 xorwf LBC,0 btfss Status,2 ; если Z=1, то следующ. инстр-я не выполн-ся goto com3 call gasim bsf GPIO, 1 ; зажечь второй светодиод goto out ;*** Проверка команды 3 *********************************** com3 movlw CMD_3 xorwf LBC,0 btfss Status,2 ; если Z=1, то следующ. инстр-я не выполн-ся goto com4 call gasim bsf GPIO, 2 ; зажечь третий светодиод goto out ;*** Проверка команды 4 *********************************** com4 movlw CMD_4 xorwf LBC,0 btfss Status,2 ; если Z=1, то следующ. инстр-я не выполн-ся goto out call gasim bsf GPIO, 4 ; зажечь четвертый светодиод ;*** Сбросить признак принятия посылки ******************** out bcf MBC,7 ; сбрасываем признак принятия посылки ;*** Пауза ************************************************ movlw TP movwf Counter3 pauset call wait decfsz Counter3,1 goto pauset return end |
Скачать готовую прошивку и asm-файл
Внимание. Во избежание затирания калибровочных констант — алгоритм заливки этой прошивки в контроллер следующий:
- Считываем текущую конфигурацию контроллера.
- Записываем значение битов калибровки схемы BOR (12-й, 13-й биты слова конфигурации, они же bandgap)
- Записываем значение последнего слова программного кода (слово по адресу 03FF) — биты калибровки генератора.
- Открываем нашу прошивку в программе программатора, и меняем в ней биты калибровки схемы BOR и генератора на считанные и записанные значения.
- Всё, теперь эту (исправленную для конкретного экземпляра PIC12) прошивку можно заливать в контроллер.