В этой статье рассмотрена простейшая программа для устройства дистанционного управления освещением на контроллере PIC12F629.
Реализованный в программе алгоритм управления позволяет устройству работать в двух режимах: обычном и дистанционном.
При включении питания (включение света настенным выключателем) контроллер открывает силовой симистор и запитывает лампу. При отключении питания (выключение света настенным выключателем) контроллер и лампа, естественно, обесточиваются. Это, собственно, и есть обычный режим работы, когда дистанционное управление отключено и лампа привычным образом управляется с помощью выключателя. Чтобы перейти в режим дистанционного управления нужно один раз нажать на кнопку нашего девайса. При этом загорается светодиод (индикация режима ДУ).
В режиме ДУ свет будет включаться/выключаться от любого сигнала, любого ИК-пульта. Это не очень удобно, поскольку при этом вы не сможете пользоваться ни одним бытовым прибором с ИК-управлением, одновременно не управляя светом, но во-первых, на то это и простейший алгоритм, а во-вторых, иногда и этого вполне достаточно. Такой девайс подойдёт людям, которым приходится часто вставать посреди ночи, например тем, у кого есть маленькие дети. Просто перед тем как ложиться спать включаете режим дистанционного управления, кладёте рядом пульт и всё. Если же вы хотите ещё и телевизор перед сном посмотреть, то придётся использовать какой-либо более сложный алгоритм. Но, об этом позже, а пока, — не будем отвлекаться.
Поскольку фотоприёмник располагается в непосредственной близости от лампы, то он принимает значительное количество ИК-помех. Для их фильтрации применён цифровой фильтр, основанный на том факте, что в большинстве ИК-протоколов длительность «единицы» более 500 мкс (например, в RC-5 длительность единицы равна 888 мкс, а в NEC — 560 мкс). То есть, если уж мы начали принимать «единицу» по одному из ИК-протоколов, то как минимум 500 мкс у нас этот сигнал будет висеть. В программе используются 4 проверки через каждые 100 мкс, и если во всех случаях сигнал присутствует, то делается вывод о том, что это не помеха, а действительно сигнал с пульта.
Далее, для того, чтобы устройство не срабатывало несколько раз от одного и того же пакета данных, после приёма каждого сигнала делается пауза на приём, длительностью более
100 мс. Такая же пауза используется для защиты от дребезга при нажатии кнопки.
Алгоритм:
![]() ![]() Итак, в аппаратной части мы имеем: входы:GP2 — приём информации от интегрального фотоприёмника,GP3 — кнопка выходы:GP0 — управление оптосимистором,GP4 — светодиод Неиспользуемые ноги микроконтроллера программируем как «выходы», генератор — внутренний |
list p = 12f629 __config 01FC4h ;*** Переменные ****************************************** CBLOCK 0x20 ; Начальный адрес блока пользовательской памяти T1 T2 ENDC ;**** Константы / Адреса регистров ************************ Status equ 03h ; выбор банка Cmcon equ 19h ; компаратор (банк 0) OSCCAL equ 10h ; хранение калибровочной константы (банк 1) INTCON equ 0Bh ; разрешение(1)/запрет(0) прерываний (любой банк) IOCB equ 16h ; регистр разрешения прерываний по GP0...GP5 INDF equ 0h ; регистр косвенной адресации FSR equ 04h ; регистр адреса при косвенной адресации GPIO equ 05h ; управление защелками порта (банк 0) TrisIO equ 05h ; выбор направления работы выводов порта (банк 1) ;********************************************************* org 0 goto start org 4 ;********************************************************* ;--- Смотрим, откуда прерывание --- btfss GPIO,3 ; если кнопка нажата - проп.следующ.команду goto priem ;--- Инвертировать светодиод --- knopka movlw .16 ; 00010000 - маска для инверсии сост-я светодиода xorwf GPIO,1 ; инвертируем состояние светодиода goto exit ;--- Если сигнал с приёмника --- priem btfsc GPIO,2 ; если на входе ILMS ноль - пришёл сигнал goto exit ;--- Проверяем, не помеха ли это --- movlw .4 movwf T1 ; кол-во циклов проверки timer movlw .25 movwf T2 ; таймер на каждую проверку time_cikl nop decfsz T2,1 goto time_cikl btfsc GPIO,2 ; если на входе 0 - подтвержд-ся сигнал и проп.выход goto exit decfsz T1,1 goto timer ;--- Если разрешено, то инвертировать состояние оптрона --- btfsc GPIO,4 ; если светодиод вкл. - пропустить следующ.команду goto exit movlw .1 ; 00000001 xorwf GPIO,1 ; после этого выход оптрона инвертируется exit call pause ; пауза bcf INTCON,0 ; сбросить флаг прерываний retfie ;********************************************************* ;*** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА ************************ ;****** Калибровка Генератора **************************** start bsf Status,5 Call 3FFh ; Загрузить калибровочную константу в w movwf OSCCAL ;*** Установка направления работы ног ******************** bcf Status,5 ; перейти в банк 0 clrf GPIO ; инициализация защелок (все выходы равны нулю) movlw .7 ; биты 0..2 поднять movwf Cmcon ; компарат.выключен, GP0,GP1,GP2 - цифров.вх/вых bsf Status,5 ; Перейти в 1-й банк movlw b'00101100' ; настройка входов/выходов movwf TrisIO bcf Status,5 ; перейти в нулевой банк ;*** Включить оптрон и погасить светодиод **************** bsf GPIO,0 ; поднять нулевой бит (включить свет) nop bsf GPIO,4 ; поднять 4-й бит (выключить светодиод) ;*** Разрешить прерывания на входах GP2, GP3 ************* bsf Status,5 ; перейти в первый банк movlw .12 ; .12 = 00001100 movwf IOCB ; разрешить прерыв.на GP2, GP3, на остальных - нет bcf Status,5 ; Перейти в 0-й банк movlw .8 ; .8 = 00001000 movwf INTCON ; разрешить прерывание от GPIO bsf INTCON,7 ; разрешить немаскированные прерывания ;-------------------- work nop ; ждём прерывание goto work ;-------------------- pause movlw .100 movwf T1 cikl1 movlw .255 movwf T2 cikl2 nop nop decfsz T2,1 goto cikl2 decfsz T1,1 goto cikl1 return end ;--------------------------------------------------------- |
Скачать готовую прошивку и asm-файл
Внимание. Во избежание затирания калибровочных констант — алгоритм заливки этой прошивки в контроллер следующий:
- Считываем текущую конфигурацию контроллера.
- Записываем значение битов калибровки схемы BOR (12-й, 13-й биты слова конфигурации, они же bandgap)
- Записываем значение последнего слова программного кода (слово по адресу 03FF) — биты калибровки генератора.
- Открываем нашу прошивку в программе программатора, и меняем в ней биты калибровки схемы BOR и генератора на считанные и записанные значения.
- Всё, теперь эту (исправленную для конкретного экземпляра PIC12) прошивку можно заливать в контроллер.
Update от 24.10.2013
Внимательные читатели заметили, что в программе выключение светодиода делается командой bsf GPIO,4. Почему так, если эта команда подаёт на ногу контроллера высокий уровень? Объясняю. Так получилось из-за того, что при разводке платы оказалось удобнее включить светик не между ногой контроллера и общим проводом (как на схеме), а между плюсом питания и ногой контроллера. В этом случае всё получается наоборот, — чтобы зажечь светодиод — нужно подать на вывод контроллера низкий уровень, а чтобы погасить — высокий.