;-- http://radiohlam.ru - собери сам, помоги собрать другу ;------------------------------------------------------------------ list p = 12f629 __config 03194h ; 01FC4h ; __CONFIG _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;03194h ;********* Переменные ************************************ 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 .0 ; номер системы CMD_1 equ .32 ; код команды 1 CMD_2 equ .16 ; код команды 2 CMD_3 equ .33 ; код команды 3 CMD_4 equ .17 ; код команды 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 ; Результат направить в регистр. GPIE equ H'0003' GIE equ H'0007' IOCB equ H'0096' IOCB5 equ H'0005' IOCB4 equ H'0004' IOCB3 equ H'0003' IOCB2 equ H'0002' IOCB1 equ H'0001' IOCB0 equ H'0000' ;******************************************************** ; Пусть у нас GP0 - выход на транзистор управления светодиода, GP1, GP2, GP4, GP5 - входы ;******************************************************** org 0 ;******** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА ******************************************************** ;*** Необходимо помнить, что калибровочные константы стираются при программировании, ********** ;*** поэтому их надо сохранять, OSCCAL хранится по адресу 03FFh, биты калибровки схемы BOR - * ;*** 12-й,13-й биты слова конфигурации (в моем случае BOR - 01, OSCCAL - 3458)***************** start ;****** Калибровка Генератора ***************************************************************** bsf Status,5 ; Call 3FFh ; Загрузить калибровочную константу в w movwf OSCCAL ; ;******** Установка направления работы выводов ************************************************ bcf Status,5 ; перейти в банк 0 clrf GPIO ; инициализация защелок (нули на всех защелках) movlw .7 ; биты 0..2 поднять (.7=b111) может b10111 = 23 ? не! movwf Cmcon ; компаратор выключен, GP0, GP1, GP2 - цифровые вх/вых bsf Status,5 ; Перейти в 1-й банк (установить в 1 5-й бит регистра Status) bcf 0x01,7 ; pull-up movlw .62 ; Записать конфигурацию GPIO в аккумулятор (W) .62=00 111110 GP0 - выход, остальные - входы movwf TrisIO ; Скопировать конфигурацию GPIO из W в регистр TrisIO. ; bcf Status,5 ; Перейти в 0-й банк (установить в 0 5-й бит регистра Status) bsf IOCB,IOCB1 bsf IOCB,IOCB2 bsf IOCB,IOCB4 bsf IOCB,IOCB5 bsf INTCON,GPIE bcf Status,5 bcf INTCON,GIE ;******** ФОРМИРОВАНИЕ СТАРШЕГО БАЙТА ПАКЕТА ************************************************* movlw Sys movwf MBC ;запись в старший разряд кода номера системы bsf MBC,6 ;установка стартбитов bsf MBC,7 ;установка стартбитов ;****** Сканирование клавиатуры ********************************************************************** main 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 ; ; sleep ; нажали кнопу любую и в слип (у меня пока сразу в него, с __config 03194h 0.2мка) bsf MBC,5 ; установить управляющий бит в 1 (первое нажатие) ; goto Scan ; ;MOVF GPIO,W ;ПЕРЕД СЛИПОМ ПРОЧИТАТЬ ПОРТ ; **** ;ВЫЧИСЛЕНИЕ НАЖАТА ЛИ КНОПКА ; BTFSS Z SLEEP ;ЕСЛИ НЕ НАЖАТО ТО В СПЯЧКУ GOTO main ;ВЫХОД ИЗ СПЯЧКИ ПО НАЖАТИЮ ;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 ; Control 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 ; признак вторичной посылки ;****** Пауза, равная межпакетному интервалу **************************************************** ;****** Пауза между пакетами равна 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 ; ;********************************************************************************************* ;***** Подпрограммы формирования и передачи логической единицы и логического нуля *********************** ;***** Передача единичного полубита ****************** RCY movlw NCr ; поместить константу NCr в аккумулятор movwf T_NC ; скопировать содержимое аккумулятора в регистр T_NC Y_001 movlw Cr1 ; поместить константу Cr1 в аккумулятор movwf T_Cr ; поместить содержимое аккумулятора в регистр T_Cr (таймер несущей) bsf GPIO,0 ; установить на выходе защелки GP0 единицу (установить 1 на выходе) Cr1_Y decfsz T_Cr,F ; декремент содержимого регистра T_Cr с ветвлением: если f=0 - результат сохраняется в аккумуляторе, если f=1 - результат ; сохраняется в регистре T_Cr. Если результат не равен 0, то исполняется следующая инструкция, если равен 0, то вместо ; следующей инструкции исполняется nop, а команда исполняется за 2 м.ц. goto Cr1_Y ; переход на метку Cr1_Y bcf GPIO,0 ; Установить на выходе защелки GP0 ноль (установить 0 на выходе) movlw Cr0 ; поместить константу Cr0 в аккумулятор movwf T_Cr ; скопировать содержимое аккумулятора в регистр T_Cr Cr0_Y decfsz T_Cr,F ; goto Cr0_Y ; decfsz T_NC,F ; goto Y_001 ; return ; ;***** Передача нулевого полубита ******************* RCN movlw NCr ; movwf T_NC ; N_001 movlw Cr1 ; movwf T_Cr ; nop ; вместо bsf GPIO nop ; дополнительно Cr1_N decfsz T_Cr,F ; goto Cr1_N ; nop nop ; вместо bсf GPIO nop ; дополнительно movlw Cr0 ; movwf T_Cr ; Cr0_N decfsz T_Cr,F ; goto Cr0_N ; decfsz T_NC,F ; goto N_001 ; return ; ;*********************************************************************************************** ; ******* SLEEP UNTIL NEXT BUTTON PRESS/RELEASE EVENT ******* ; QUIRK: we may omit LED blanking if go to check_switch ;все ниже я заремил пока ;wait4release ; bcf GPIO,4 ;wait4release_l1 ; call getkeys ; btfss keys,0 ; goto wait4release_l1 ; btfss keys,1 ; goto wait4release_l1 ; IFDEF __12F675 ; movlw (1 << GPIE) ; movwf INTCON ; set wakeup when GP0 or GP1 changed, w/o interrupt ; and clear GPIF flag ; ENDIF ; sleep ; goto reinit ;ниже просто куски ;wait4release заюзан еще так: ;goto wait4release ; secondary button released ;check_key0 ; btfsc keys,0 ; goto wait4release ; а wait4release_l1 тока тут в слипе ; ниже переход на getkeys ; ------- get button state with suppress of the chatter of switching contacts ;getkeys ; movlw 0x3 ; clrf counter_lo ;getkeys_l1 ; andwf GPIO,w ; goto $+1 ; goto $+1 ; decfsz counter_lo,f ; goto getkeys_l1 ; movwf keys ; retlw 0 ; 2052 cycles ; getkeys_l1 тока вон выше по кругу ;MOVF GPIO,W ;ПЕРЕД СЛИПОМ ПРОЧИТАТЬ ПОРТ ; **** ;ВЫЧИСЛЕНИЕ НАЖАТА ЛИ КНОПКА ; BTFSS Z ; SLEEP ;ЕСЛИ НЕ НАЖАТО ТО В СПЯЧКУ ; GOTO MAIN ;ВЫХОД ИЗ СПЯЧКИ ПО НАЖАТИЮ end