Программа, рассмотренная в этой статье, разработана специально для самодельного ИК-пульта дистанционного управления на контроллере PIC12F629. Если вы измените аппаратную часть (например, будете использовать другой порядок ног, повесите внешний генератор), то программу также нужно будет переделать.
Прежде чем разбираться с программой, наверное, каждому будет полезно посмотреть описание протокола RC-5.
Алгоритм:
Итак, пусть в аппаратной части мы имеем:
входы: GP5 — кнопка SB1, GP2 — кнопка SB2, GP4 — кнопка SB3, GP1 — кнопка SB4
выходы: GP0 — вывод информации по протоколу RC-5.
MCLR внешне подтянут к питанию; используется внутренний генератор.
Пусть мы планируем управлять светом, то есть номер системы будет 29.
list p = 12f629 __config 01FE4h ;*** Переменные ****************************************** CBLOCK 0x20 ; Начальный адрес блока пользовательской памяти T_Cr ; таймер несущей T_NC ; счетчик количества импульсов в пакете T_0 ; таймер интервала между пакетами LBC ; младший байт посылки MBC ; старший байт посылки ENDC ;*** Константы / Адреса регистров ************************ Cr1 equ .2 ; длительность 1 несущей Cr0 equ .4 ; длительность 0 несущей NCr equ .32 ; кол-во имп-сов несущей в одном пакете (полбита = 889uS) Sys equ .29 ; номер системы 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 ; Результат направить в регистр ;******************************************************** org 0 ;*** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА *********************** ;*** Калибровка Генератора ****************************** 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 .62 ; Записать конфигурацию GPIO в аккумулятор (W) ; .62=00 111110 GP0 - выход, остальные - входы movwf TrisIO ; Скопировать конфигурацию GPIO из W в регистр TrisIO bcf Status,5 ; Перейти в 0-й банк ;*** ФОРМИРОВАНИЕ СТАРШЕГО БАЙТА ПАКЕТА ***************** movlw Sys movwf MBC ; запись в старший разряд кода номера системы bsf MBC,6 ; установка стартбита bsf MBC,7 ; установка стартбита ;*** СКАНИРОВАНИЕ КЛАВИАТУРЫ **************************** Scan btfss GPIO,5 ; если на входе GP5 низкий уровень - нажата клавиша 1 goto Tx_CMD1 btfss GPIO,2 ; если на входе GP2 низкий уровень - нажата клавиша 2 goto Tx_CMD2 btfss GPIO,4 ; если на входе GP4 низкий уровень - нажата клавиша 3 goto Tx_CMD3 btfss GPIO,1 ; если на входе GP1 низкий уровень - нажата клавиша 4 goto Tx_CMD4 bsf MBC,5 ; установить управляющий бит в 1 (первое нажатие) goto Scan ;*** ФОРМИРОВАНИЕ МЛАДШЕГО БАЙТА ПАКЕТА ***************** Tx_CMD1 movlw CMD_1 movwf LBC ; запись номера команды 1 в младший разряд кода goto TxRC ;******************************************************** Tx_CMD2 movlw CMD_2 movwf LBC ; запись номера команды 2 в младший разряд кода goto TxRC ;******************************************************** Tx_CMD3 movlw CMD_3 movwf LBC ; запись номера команды 3 в младший разряд кода goto TxRC ;******************************************************** Tx_CMD4 movlw CMD_4 movwf LBC ; запись номера команды 4 в младший разряд кода goto TxRC ;*** ПЕРЕДАЧА ПАКЕТА RC-5 ********************************* TxRC btfsc MBC,7 ; Startbit 1. Если он = 1, то выполняется Tx_1, call Tx_1 ; если он равен нулю, то выполняется Tx_0 btfss MBC,7 ; аналогично остальные биты call Tx_0 ;-------------------------------- btfsc MBC,6 ; Startbit 2 call Tx_1 btfss MBC,6 call Tx_0 ;-------------------------------- btfsc MBC,5 ; Toggle bit call Tx_1 btfss MBC,5 call Tx_0 ;-------------------------------- btfsc MBC,4 ; System bit 4 call Tx_1 btfss MBC,4 call Tx_0 ;-------------------------------- btfsc MBC,3 ; System bit 3 call Tx_1 btfss MBC,3 call Tx_0 ;-------------------------------- btfsc MBC,2 ; System bit 2 call Tx_1 btfss MBC,2 call Tx_0 ;-------------------------------- btfsc MBC,1 ; System bit 1 call Tx_1 btfss MBC,1 call Tx_0 ;-------------------------------- btfsc MBC,0 ; System bit 0 call Tx_1 btfss MBC,0 call Tx_0 ;-------------------------------- btfsc LBC,5 ; Command bit 5 call Tx_1 btfss LBC,5 call Tx_0 ;-------------------------------- btfsc LBC,4 ; Command bit 4 call Tx_1 btfss LBC,4 call Tx_0 ;-------------------------------- btfsc LBC,3 ; Command bit 3 call Tx_1 btfss LBC,3 call Tx_0 ;-------------------------------- btfsc LBC,2 ; Command bit 2 call Tx_1 btfss LBC,2 call Tx_0 ;-------------------------------- btfsc LBC,1 ; Command bit 1 call Tx_1 btfss LBC,1 call Tx_0 ;-------------------------------- btfsc LBC,0 ; Command bit 0 call Tx_1 btfss LBC,0 call Tx_0 bcf MBC,5 ; установить управляющий бит в 0 (повторное нажатие) ;*** ПАУЗА, РАВНАЯ МЕЖПАКЕТНОМУ ИНТЕРВАЛУ *************** ;*** Пауза между пакетами равна 50 bit, ***************** ;*** т.е. надо послать 100 нулевых полубитов (RCN) ****** movlw .99 ; здесь записано 99, а не 100, т.к. далее ; call стоит раньше декремента movwf T_0 pause call RCN decfsz T_0,F ; декремент T_0 goto pause goto Scan ;*** КОНЕЦ ОСНОВНОЙ ПРОГРАММЫ *************************** ;*** ПОДПРОГРАММЫ ПЕРЕДАЧИ НУЛЯ И ЕДИНИЦЫ *************** ;*** Передача нуля манчестерским кодом ****************** Tx_0 call RCY ; первые полбита единица call RCN ; вторые полбита ноль return ;*** Передача единицы манчестерским кодом *************** Tx_1 call RCN ; первые полбита ноль call RCY ; вторые полбита единица return ;******************************************************** ;*** ПОДПРОГРАММЫ ФОРМИРОВАНИЯ СОСТОЯНИЙ "ON" И "OFF" *** ;*** Передача единичного полубита ("ON") **************** RCY movlw NCr ; поместить константу NCr в аккумулятор movwf T_NC ; скопировать содержимое аккумулятора в регистр T_NC Y_001 movlw Cr1 ; поместить Cr1 в аккумулятор (изменяя Cr1 и Cr0 можно ; грубо подстраивать частоту несущей) movwf T_Cr ; поместить содерж.аккум-ра в T_Cr (таймер несущей) bsf GPIO,0 ; установить на выходе GP0 единицу Cr1_Y decfsz T_Cr,F ; декремент T_Cr с ветвлением: если f=0 - результат ; сохр-ся в аккум., если f=1 - результат сохр-ся в T_Cr goto Cr1_Y nop ; добавляя еще nop - можно подстр-ть частоту несущей bcf GPIO,0 ; Установить на выходе GP0 ноль movlw Cr0 ; поместить Cr0 в аккумулятор (изменяя Cr1 ; и Cr0 можно грубо подстраивать частоту несущей) movwf T_Cr ; скопировать содержимое аккумулятора в регистр T_Cr Cr0_Y decfsz T_Cr,F goto Cr0_Y ; для точной подстройки чатоты несущей decfsz T_NC,F goto Y_001 return ;***** Передача нулевого полубита ("OFF") ******************* RCN movlw NCr ; подпр. передачи 0-го полубита имеет ту же структуру, movwf T_NC ; что и подпрограмма передачи единичного полубита, N_001 movlw Cr1 ; чтобы было легче регулировать их длительности movwf T_Cr nop ; вместо bsf GP0 nop ; дополнительно Cr1_N decfsz T_Cr,F goto Cr1_N nop nop ; вместо bсf GP0 nop ; дополнительно movlw Cr0 movwf T_Cr Cr0_N decfsz T_Cr,F goto Cr0_N decfsz T_NC,F goto N_001 return ;********************************************************* end |
Скачать готовую прошивку и asm-файл
Внимание. Во избежание затирания калибровочных констант — алгоритм заливки этой прошивки в контроллер следующий:
- Считываем текущую конфигурацию контроллера.
- Записываем значение битов калибровки схемы BOR (12-й, 13-й биты слова конфигурации, они же bandgap).
- Записываем значение последнего слова программного кода (слово по адресу 03FF) — биты калибровки генератора.
- Открываем нашу прошивку в программе программатора, и меняем в ней биты калибровки схемы BOR и генератора на считанные и записанные значения.
- Всё, теперь эту (исправленную для конкретного экземпляра PIC12) прошивку можно заливать в контроллер.
Если интересно — можете посмотреть для сравнения аналогичную программу для ATtiny13 (алгоритм абсолютно такой же, отличается только порядок ног).