;-----ОПРЕДЕЛЕНИЕ АДРЕСОВ----- CNT1 equ d'184' ;125 136 149 184 231 254 CNT2 equ d'70' ;102 94 86 70 56 51 w equ 0x00 ; f equ 0x01 ; TMR equ 0x01 ; STATUS equ 0x03 ; FSR equ 0x04 ; PCL equ 0x02 ; PCH equ 0x0A ; INTCON equ 0x0B ; EEDATA equ 0x08 ; EEADR equ 0x09 ; ADR_DP equ 0x3f ;адрес диапазона во FLASH ADR_SO equ 0x3e ;адрес слова сост. во FLASH ADR_CG equ 0x3d ;адрес калибр. конст. генер. ADR_MS equ 0x3b ;адрес маски операций с ПЧ ; для каждого диапазона ;-----Назначение выводов микроконтроллера----- MAS_LCD equ b'11111100' ;инверсная маска индикатора #define LCD_C 0x86, 0 ;\ Индикатор - DATA #define LCD_D 0x86, 1 ;/ Индикатор - CLK #define DP_T 0x05, 2 ;\ Уст. Диапазона (T - ИЕ8) #define DP_R 0x05, 1 ;/ Уст. Диапазона (R - ИЕ8) #define ARU 0x06, 7 ;Вывод "АРУ" #define ATT 0x05, 0 ;Вывод "АТТ" #define RA3 0x85, 3 ;Выход счетчика - RA3 #define PTT 0x06, 6 ;Вход РРТ #define SA1 0x06, 2 ;Клавиша "SA1" #define SA2 0x06, 3 ;Клавиша "SA2" #define SA3 0x06, 4 ;Клавиша "SA3" #define SA4 0x06, 5 ;Клавиша "SA4" DEC12 equ 0x0c ;\ DEC34 equ 0x0d ; | DEC56 equ 0x0e ; |значение индикатора DEC78 equ 0x0f ; | DEC910 equ 0x10 ;/ FREQ_L equ 0x11 ;рабочая частота (мл.) FREQ_M equ 0x12 ;рабочая частота (ср.) FREQ_H equ 0x13 ;рабочая частота (ст.) DATA1 equ 0x14 ;\ DATA2 equ 0x15 ; | DATA3 equ 0x16 ; | регистры общего DATA4 equ 0x17 ; | использования DATA5 equ 0x18 ; | DATA6 equ 0x19 ;/ COUNT1 equ 0x1a ;\ регистры задержки COUNT2 equ 0x1b ;/ OSN_C equ 0x1c ;счетчик основного цикла TEMP_F equ 0x1d ;последнее значение частоты GENER equ 0x1e ;колибровочная константа ген. SOST equ 0x1f ;флаги состояния устройства: #define AR SOST, 0 ; -состояние АРУ #define AT SOST, 1 ; -состояние АТТ #define KV_UKV SOST, 2 ; -режим КВ/УКВ #define PTT_IN SOST, 3 ; -режим входа РТТ #define GEN SOST, 7 ; -режим калибр. генератора list p=16f84a __config b'11111111111001' org 0x2100 ;записать данные во FLASH DE 0x00,0x00,0x00 ;нач. знач. ПЧ = 0 org 0x213d ; DE d'128' ;калибр. конст. = 128 DE b'00000000' ;слово сотояния = 0 DE b'10100001' ;макс. диап=10, текущ = 1 org 2 ;адрес начала программы START call PAUSE ;\ задержка 0.2 секунда call PAUSE ;/ clrf 0x05 ;очистить Port A bsf SOST, 5 ;для установки диапазона clrf 0x06 ;очистить Port B ;-----ОБНОВЛЕНИЕ СОСТОЯНИЯ СПЕЦ. РЕГИСТРОВ----- ; (выполняется каждую секунду) NEW_I clrf INTCON ;запретить прерывание movlw b'00010000' ;\обновление Tris A tris 0x05 ;/ movlw b'01111100' ;\обновление Tris B tris 0x06 ;/ movlw b'00100111' ;\обновление option option ;/ movlw d'20' ;\ установить основной цикл movwf OSN_C ;/ программы (20*50мс=1сек) comf TEMP_F, f ;изменить значение TEMP btfsc SOST, 5 ;\если первый раз, то call DP_IE8 ;/ установить диапазон в ИЕ8 call LOAD_SO ;загрузить слово состояние call USATAR ;обновить состояние ATT,ARU call LOAD_CG ;загрузить калибр. константу bcf SOST, 5 ; ;-----ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ----- OSNOV movlw d'50' ;\задержка 10 мс call PAUS10 ;/ call COUNTER ;определить частоту (40мс) call KLAV ;опрос кнопок movf TEMP_F, w ;\ если частота не менялась, subwf FREQ_L, w ; } то не обновлять индикатор btfss STATUS, 2 ;/ call F_LCD ;вывод частоты на индикатор decfsz OSN_C, f ;декремент цикла goto OSNOV ;\ каждую секунду переходить goto NEW_I ;/ на обновл. основ. регис. ;-----ОПРОС КНОПОК----- KLAV movlw d'20' ;\ цикл для задержки в 2 сек movwf DATA1 ;/ для опред. нажат. клав. ; comf 0x06, w ;\считать порт andlw b'000111100' ;/ btfsc STATUS, 2 ;\если ничего не нажато, return ;/ то вернуться ; kl_cl movwf FSR ;состояние порта в FSR call PAUSE ;задержка 0.1 сек call LCD ;обновить индикатор comf 0x06, w ;\считать порт andlw b'000111100' ;/ btfsc STATUS, 2 ;\ goto small ; \определить длительность decfsz DATA1, f ; / удержания клавиши goto kl_cl ;/ ;-----опред. клавишу, если длител. нажатия более 2 сек----- _high clrf PCH ;первый блок (256) rrf FSR, f ; rrf FSR, f ; movlw b'00001111' ;\ оставить младший полубайт andwf FSR, w ;/ addwf PCL, f ;прабавить к прог. счетч. ; _0000 return ; не задействовано _0001 goto UST_MS ;устан. опер. с ПЧ (F+ПЧ) _0010 goto UST_MS ;устан. опер. с ПЧ (F-ПЧ) _0011 goto MAX_DP ;устан. число диапазонов _0100 goto IN_PR ;ввод ПЧ _0101 goto UST_PTT ;устан. реж. входа РТТ _0110 goto UST_PTT ;устан. реж. входа РТТ _0111 return ; не задействовано _1000 goto UST_RAZ ;изм. режим отображения _1001 return ; не задействовано _1010 return ; не задействовано _1011 return ; не задействовано _1100 goto CAL_GEN ;перейти на CALIBR_GEN _1101 return ; не задействовано _1110 return ; не задействовано _1111 return ; не задействовано ;-----опред. клавишу, если длител. нажатия менее 2 сек----- small btfsc FSR, 2 ;\если нажата "UP", то goto DIAP_UP ;/ перейти на DIAP_UP btfsc FSR, 3 ;\если нажата "DOWN", то goto DIAP_DN ;/ перейти на DIAP_DN goto AT_AR ;иначе перейти на AT_AT ;-----УСТАНОВИТЬ РЕЖИМ ВХОДА РТТ----- UST_PTT movlw b'11111111' ;\ movwf DEC12 ; | movwf DEC34 ; |на индикаторе "----XX----" movwf DEC78 ; | movwf DEC910 ;/ movlw b'11100101' ;отобразить "PS" btfss FSR, 0 ; movlw b'10111110' ;отобразить "FP" movwf DEC56 ; bcf PTT_IN ;режим "PS" btfss FSR, 0 ; bsf PTT_IN ;режим "FP" call SAVE_SO ;сохранить слово состояния goto END_SA ;выйти и ждать отж. кноп. ;-----УСТАНОВКА КОЛИЧЕСТВА ИСПОЛЬЗУЕМЫХ ДИАПАЗОНОВ----- MAX_DP movlw b'11111111' ;\ movwf DEC12 ; | movwf DEC34 ; |на индикаторе "----XX----" movwf DEC78 ; | movwf DEC910 ;/ call LOAD_DP ;\загрузить текущий диапазон movwf COUNT1 ;/ andlw b'11110000' ;\ определить: sublw b'10100000' ; \ заблокировать (ON) btfss STATUS, 2 ; / или разблокировать (OFF) goto OFF_D ;/ ; ON_D movlw b'00001111' ;\ andwf EEDATA, f ; |переслать номер текущего movf EEDATA, w ; | диапазона в номер movwf DEC56 ; | максимального диапазона swapf EEDATA, w ; | addwf EEDATA, f ;/ movlw d'10' ;\ subwf DEC56, w ; |если диапазон = 10, movlw b'00011010' ; | то записать в разряд btfsc STATUS, 2 ; | индикатора '00011010' movwf DEC56 ; | goto lcd_d ;/ ; OFF_D movlw b'00001111' ;\ andwf EEDATA, f ; |записать в номер максим. movlw b'10100000' ; | знач. диапазона число 10 addwf EEDATA, f ;/ ;/ movlw b'00011010' ;\записать в разряд movwf DEC56 ;/ индикатора '00011010' ; lcd_d call SV_DP ;сохранить во FLASH call LCD ;вывести на индикатор goto END_SA ;выйти ;-----ВВОД ПРОМЕЖУТОЧНОЙ ЧАСТОТЫ----- IN_PR clrf FREQ_L ;\ clrf FREQ_M ; }очистить значение частоты clrf FREQ_H ;/ movlw d'6' ;\цикл ввода разрядов movwf FSR ;/ (6 разрядов) ; NX_SM incf FREQ_L, f ;правый разряд+1 movlw b'00001111' ;\ andwf FREQ_L, w ; | sublw d'10' ; |если число больше 9, movlw b'11110000' ; | то установить 0 btfsc STATUS, 2 ; | andwf FREQ_L, f ;/ call out_pr ;вывести на индикатор call END_SN ;ждать отжатия клавиши ; cicl_pr call out_pr ;вывести на индикатор btfss SA3 ;ждать нажатия клавиши goto op_nk ;если нажата, то goto: op_nk call PAUSE ;задержка 0.1 сек goto cicl_pr ;продолжить цикл ожидания ; op_nk movlw d'10' ;\цикл задержки в 1 сек movwf DATA1 ;/ cnk btfsc SA3 ;\если нажата менее 1 сек, goto NX_SM ;/ то след. знач. разряда call PAUSE ;задержка 0.1 сек decfsz DATA1, f ;\если нажата более 1 сек, goto cnk ;/ то следующий разряд ; NX_RZ decfsz FSR, f ;\ продолжить цикл ввода goto nxr ; } если введены все 6 разр., goto end_rz ;/ то завершить ; nxr movlw d'4' ;\ movwf COUNT1 ; | nx_rzz bcf STATUS, 0 ; | rlf FREQ_L, f ; |перейти на следующий rlf FREQ_M, f ; |разряд rlf FREQ_H, f ; | decfsz COUNT1, f ; | goto nx_rzz ;/ goto NX_SM ; ; out_pr movf FREQ_L, w ;\ movwf DATA4 ; | movf FREQ_M, w ; | movwf DATA5 ; | movf FREQ_H, w ; | movwf DATA6 ;/ movlw b'11111111' ;\выводить нули сразу movwf COUNT2 ;/ call end_bcd ;BCD преобразование goto LCD ;обновить индикатор ; end_rz movlw d'6' ;\ цикл десятично-двоичного movwf COUNT1 ;/ преобразования (6 разр.) clrf DATA4 ;\ clrf DATA5 ; }очистить clrf DATA6 ;/ ;-----Десятично-двоичное преобразование---- DCB call LD_ZN ;загрузить значение константы movf FREQ_L, w ;\ определить количество andlw b'00001111' ; | сложений movwf COUNT2 ; | если 0 раз, то btfsc STATUS, 2 ; | сразу перейти к goto fr_nx ;/ следующему разряду ; dcb_c movf DATA3, w ;\ сложить старший байт addwf DATA6, f ;/ movf DATA2, w ;\ сложить средний байт addwf DATA5, f ;/ btfsc 0x03, 0 ;\ если переполнился, то incf DATA6, f ;/ прибавить 1 к старшему movf DATA1, w ;\ сложить младший байт addwf DATA4, f ;/ btfss 0x03, 0 ;\ если переполнился, то goto dcb_cc ; \ прибавить 1 к среднему movlw 0x01 ; / иначе закончить сложение addwf DATA5, f ;/ btfsc 0x03, 0 ;\ если переполн. опять, то addwf DATA6, f ;/ прабавить 1 уже к старшему dcb_cc decfsz COUNT2, f ;\продолжить цикл сложения goto dcb_c ;/ (сложить COUNT1 раз) ; fr_nx movlw d'4' ;\ movwf COUNT2 ; | fr_nxx bcf STATUS, 0 ; | rrf FREQ_H, f ; |перейти на следующий rrf FREQ_M, f ; | разряд преобразования rrf FREQ_L, f ; | decfsz COUNT2, f ; | goto fr_nxx ;/ decfsz COUNT1, f ;\если преобраз. все 6 разр., goto DCB ;/ то закончить преобразов. ; call SAVE_PR ;сохранить ПЧ call F_LCD ;обновить индикатор goto END_SA ;завершить ввод ПЧ ; LD_ZN clrf PCH ;первый блок 256 call ustz_L ;\загрузить младш. байт movwf DATA1 ;/ call ustz_M ;\загрузить средн. байт movwf DATA2 ;/ call ustz_H ;\загрузить старш. байт movwf DATA3 ;/ return ;вернуться ; ustz_L movf COUNT1, w ; addwf PCL, f ; nop ; retlw 0xa0 ;100000, младший retlw 0x10 ; 10000, младший retlw 0xe8 ; 1000, младший retlw 0x64 ; 100, младший retlw 0x0a ; 10, младший retlw 0x01 ; 1, младший ; ustz_M movf COUNT1, w ; addwf PCL, f ; nop ; retlw 0x86 ;100000, средний retlw 0x27 ; 10000, средний retlw 0x03 ; 1000, средний retlw 0x00 ; 100, средний retlw 0x00 ; 10, средний retlw 0x00 ; 1, средний ; ustz_H movf COUNT1, w ; addwf PCL, f ; nop ; retlw 0x01 ;100000, старший retlw 0x00 ; 10000, старший retlw 0x00 ; 1000, старший retlw 0x00 ; 100, старший retlw 0x00 ; 10, старший retlw 0x00 ; 1, старший ;-----РЕЖИМ КАЛИБРОВКИ ГЕНЕРАТОРА----- CAL_GEN bsf GEN ;установить флаг режима call out_cal ;обновить индикатор call END_SN ;ждать отжатия клавиши ; cic_cal btfss SA1 ;\если нажата "UP", то goto up_cal ;/ увелич. знач. конст. на 1 btfss SA2 ;\если нажата "UP", то goto dn_cal ;/ уменьш. знач. конст. на 1 btfss SA3 ;\ goto end_cal ; \если нажата SA3 или SA4, btfss SA4 ; / то выйти из режима goto end_cal ;/ калибровки ; nx_cal call out_cal ;вевести на индикатор goto cic_cal ;продолжить цикл настр. ген. ; out_cal call COUNTER ; movf GENER, w ;\ movwf DATA1 ; |сделать BCD преобразование clrf DATA2 ; |для калибровочной clrf DATA3 ; |константы call BCD ;/ swapf DEC34, w ;\ andlw b'11110000' ; | movwf DEC910 ; | swapf DEC12, w ; |перенести значение andlw b'00001111' ; |в правый угол индикатора addwf DEC910, f ; | swapf DEC12, w ; | andlw b'11110000' ; | movwf DEC78 ;/ call F_LCD ;вывести частоту и константу goto PAUSE ;на индикатор ; up_cal incfsz GENER, f ;GEN + 1 goto nx_cal ;если переполнился, incf GENER, f ; то GEN=1 goto nx_cal ;продолжить цикл настр. ген. ; dn_cal decfsz GENER, f ;GEN + 1 goto nx_cal ;если переполнился, decf GENER, f ; то GEN=255 goto nx_cal ;продолжить цикл настр. ген. ; end_cal movlw b'00001111' ;\очистить флаг andwf SOST, f ;/ настройки генератора call SAVE_CG ;сохранить call F_LCD ;вывести частоту на индикатор goto END_SA ;выйти ;-----ВКЛЮЧЕНИЕ / ВЫКЛЮЧЕНИЕ "АТТ" и "АРУ"----- AT_AR btfss FSR, 4 ;определить нажатую goto off_at ; клавишу ; off_ar btfss AR ;если АРУ выключено, goto on_ar ;то включить, bcf AR ;иначе выключить goto ustr ; on_ar bsf AR ; goto ustr ; ; off_at btfss AT ;если АТТ выключено, goto on_at ;то включить, bcf AT ;иначе выключить goto ustr ; on_at bsf AT ; ustr call SAVE_SO ;сохранить слово состояния ; USATAR btfsc AT ;\ bsf ATT ; \установить состояние btfss AT ; / вывода "ATT" bcf ATT ;/ btfsc AR ;\ bsf ARU ; \установить состояние btfss AR ; / вывода "АРУ" bcf ARU ;/ return ;выйти ;-----ИЗМЕНЕНИЕ РЕЖИМА ОТОБРАЖЕНИЯ РАЗРЯДОВ НА ИНДИКАТОРЕ----- UST_RAZ btfss KV_UKV ;\ если был "КВ", то goto ust_1 ; } ust_0 bcf KV_UKV ;/ переделать на "УКВ" goto sav_r ; иначе ust_1 bsf KV_UKV ;переделать на "КВ" ; sav_r call SAVE_SO ;сохранить слово состояния call F_LCD ;обновить индикатор call SAVE_SO ;сохранить слово состояния goto END_SA ;ждать отжатия клавиши ;-----ЗАПИСЬ РЕЖИМА ОПЕРАЦИИ С ПЧ НА ТЕКУЩ. ДИАПАЗ.----- UST_MS call LOAD_MS ;загруз. маску операций с ПЧ call LOAD_DP ;\ andlw b'00001111' ; |загрузить текущ. диапазон movwf DATA1 ; | movwf DATA2 ;/ movwf DEC910 ;переслать диап. в DEC910 sublw d'10' ;\ если Диап=10, то movlw b'00011010' ; |записать "00011010" btfsc STATUS, 2 ; | movwf DEC910 ;/ ; ms_c1 rrf COUNT2, f ;\ rrf COUNT1, f ; | rrf DATA4, f ; |перейти на флаг rrf DATA3, f ; | текущего диапазона decfsz DATA1, f ; | goto ms_c1 ;/ ; bcf DATA4, 7 ;\ ; btfsc FSR, 0 ; | bsf DATA4, 7 ; |установить режим movlw b'00000001' ; | вычисления ПЧ btfss DATA4, 7 ; | movlw b'11110001' ; | movwf DEC56 ;/ ; ms_c2 rlf DATA3, f ;\ rlf DATA4, f ; | rlf COUNT1, f ; |восстановить rlf COUNT2, f ; | decfsz DATA2, f ; | goto ms_c2 ;/ ; movlw ADR_MS ;\ ; movwf EEADR ; | movf COUNT2, w ; | movwf EEDATA ; | call SAVE ; |записать во FLASH incf EEADR, f ; | movf COUNT1, w ; | movwf EEDATA ; | call SAVE ;/ ; clrf DEC12 ;\ clrf DEC34 ; }очистить неиспользованные clrf DEC78 ;/ разряды индикатора goto END_SA ;ждать отжатия клавиши ;-----ПЕРЕКЛЮЧЕНИЕ ДИАПАЗОНА ВВЕРХ (~10ms. 17б)----- DIAP_UP call LOAD_DP ;загрузить диапазон movwf COUNT1 ;текущий диапазон movwf COUNT2 ;макс. число диапазонов swapf COUNT2, f ; movlw b'00001111' ; andwf COUNT1, f ; andwf COUNT2, w ; subwf COUNT1, w ;\ если уже максимальный, то btfsc STATUS, 2 ; } не переключать return ;/ movlw d'10' ; subwf COUNT1, w ;\ если DIAP=10, то btfsc STATUS, 2 ; } не переключать return ;/ incf EEDATA, f ;DIAP + 1 call SV_DP ;сохранить текущий диапазон goto DP_IE8 ;установить в ИЕ8 ;-----ПЕРЕКЛЮЧЕНИЕ ДИАПАЗОНА ВНИЗ ( ~10ms. 6б)----- DIAP_DN call LOAD_DP ;загрузить диапазон andlw b'00001111' ; movwf COUNT1 ; decfsz COUNT1, w ;\ если DIAP=1, то goto Dn1 ; } не переключать return ;/ Dn1 decf EEDATA, f ;DIAP - 1 call SV_DP ;сохранить текущ. диапаз. goto DP_IE8 ;установить в ИЕ8 ;-----ОЖИДАНИЕ ОТЖАТИЯ КЛАВИШ----- END_SA call DP_IE8 ;обновить ИЕ8 END_SN call LCD ;обновить индикатор call PAUSE ;задерка 0.1 сек comf 0x06, w ;считать порт andlw b'000111100' ;проверить клавиши btfss STATUS, 2 ;если не все отжаты, то goto END_SN ;ждать, иначе comf TEMP_F, f ;изменить значение TEMP return ;вернуться ;-----УСТАНОВКА ДИАПАЗОНА В К561ИЕ8 (~50 цикл. 14б)----- DP_IE8 call LOAD_DP ; bsf DP_R ;RESET andlw b'00001111' ; movwf COUNT1 ; bcf DP_R ;убрать RESET decfsz COUNT1, f ; goto dp_ie ; return ; dp_ie bsf DP_T ; nop ; bcf DP_T ; decfsz COUNT1, f ;декремент цикла или выйти goto dp_ie ; return ; ;-----ОПРЕДЕЛЕНИЕ ЧАСТОТЫ ИМПУЛЬСОВ (40ms)----- COUNTER; return movf GENER, w ;\переслать калибр. конст. movwf FSR ;/ в FSR clrf INTCON ;очистить все флаги clrf FREQ_H ;очистить старший байт clrf TMR ;очистить счетчик movlw CNT2 ;\ определить старший movwf COUNT2 ;/ цикл задержки (40мс) ; bsf STATUS, 5 ;банк1 bsf RA3 ;RA3 на ввод (начало счета) bcf STATUS, 5 ;банк0 ;-----Счет----- CNT movlw CNT1 ;\ определить младший movwf COUNT1 ;/ цикл задержки (40мс) Paus decfsz COUNT1, f ;\ декремент младшего цикла goto Paus ;/ call TMR_INT ;определ. переполн. таймера decfsz COUNT2, f ;\ декремент старшего цикла goto CNT ;/ ; CL_GN nop ;\ реализация калибровки decfsz FSR, f ; } генератора goto CL_GN ;/ call TMR_INT ;определ. переполн. таймера ;-----завершение счета----- Stop bcf RA3 ;RA3 в 0 bsf STATUS, 5 ;банк1 bcf RA3 ;RA3 на вывод (конец счета) bcf STATUS, 5 ;банк0 call TMR_INT ;определ. переполн. таймера ;-----Определение младшего байта счетчика----- TMR_LOW movf TMR, w ;\ movwf FREQ_M ;/ TMR -> FREQ_M clrf FREQ_L ;очистить младший байт ; Cnt bsf RA3 ;установить лог.1 incf FREQ_L, f ; bcf RA3 ;установить лог.0 nop ; movf TMR, w ;TMR --> W subwf FREQ_M, w ;\ btfsc STATUS, 2 ; }ждать переполнения TMR_L goto Cnt ;/ incf FREQ_L, f ; comf FREQ_L, f ; incf FREQ_L, f ; incf FREQ_L, f ; ; bcf STATUS, 0 ;очистить carry rrf FREQ_H, f ;\ rrf FREQ_M, f ; \ rrf FREQ_L, f ; | bcf STATUS, 0 ; |деление на 4 rrf FREQ_H, f ; | rrf FREQ_M, f ; / rrf FREQ_L, f ;/ ; btfsc GEN ;\если режим калибр. ген, то return ;/ не производить вычисление ; btfsc PTT_IN ;определить текущ. режим goto opr_ptt ; входа РТТ ; btfss PTT ;\если РТТ задействован, то return ;/ не производить вычисление ; call LOAD_DP ;загрузить текущий диапазон andlw b'00001111' ;\оставить младший байт movwf FSR ;/ call LOAD_MS ;загруз. маску операций с ПЧ opr_op rrf COUNT2, f ;\ rrf COUNT1, f ; | decfsz FSR, f ; |определить для текущего goto opr_op ; |диапазона операцию с ПЧ btfss STATUS, 0 ; | goto SUB_PR ; | goto ADD_PR ;/ ; opr_ptt btfss PTT ;если на входе РТТ лог0, goto SUB_PR ; то Fвх-ПЧ, goto ADD_PR ; иначе Fвх+ПЧ ;-----обработка переполнения TMR----- TMR_INT btfss INTCON, 2 ;\ если TMR переполнился, goto NoTMR ;/ то FREQ_H + 1 bcf INTCON, 2 ;очистить флаг переполнения incf FREQ_H, f ; return ; NoTMR nop ; return ; ;-----ВЫЧИТАНИЕ ПРОМЕЖУТОЧНОЙ ЧАСТОТЫ (15б)----- SUB_PR call LOAD_PR ;обнов. значение пром. част. movf DATA6, w ;\ вычесть старший байт subwf FREQ_H, f ;/ movf DATA5, w ;\ вычесть младший байт subwf FREQ_M, f ;/ btfss 0x03, 0 ;\ если не хватило, то decf FREQ_H, f ;/ вычесть 1 из старшего movf DATA4, w ;\ вычесть младший байт subwf FREQ_L, f ;/ btfsc 0x03, 0 ;\ если не хватило, то return ; \ вычесть 1 из среднего movlw 0x01 ; / иначе закончить вычитание subwf FREQ_M, f ;/ btfss 0x03, 0 ;\ если опять не хватило, то subwf FREQ_H, f ;/ вычесть 1 уже из старшего return ;закончить вычитание ;-----ПРИБАВЛЕНИЕ ПРОМЕЖУТОЧНОЙ ЧАСТОТЫ (16б)----- ADD_PR call LOAD_PR ;обнов. значение пром. част. movf DATA6, w ;\ сложить старший байт addwf FREQ_H, f ;/ movf DATA5, w ;\ сложить средний байт addwf FREQ_M, f ;/ btfsc 0x03, 0 ;\ если переполнился, то incf FREQ_H, f ;/ прибавить 1 к старшему movf DATA4, w ;\ сложить младший байт addwf FREQ_L, f ;/ btfss 0x03, 0 ;\ если переполнился, то return ; \ прибавить 1 к среднему movlw 0x01 ; / иначе закончить сложение addwf FREQ_M, f ;/ btfsc 0x03, 0 ;\ если переполн. опять, то addwf FREQ_H, f ;/ прабавить 1 уже к старшему return ;закончить сложение ;-----ДВОИЧНО-ДЕСЯТИЧНОЕ ПРЕОБРАЗОВАНИЕ (106б)----- BCD clrf DATA4 ;\ clrf DATA5 ; }очистить предыдущее знач. clrf DATA6 ;/ ; movlw d'20' ;\цикл преобразования movwf COUNT1 ;/макс. число = 2^20=1048576 ; bcd1 movf DATA4, w ; call bcd_l ; addwf DATA4, f ; bcd2 movf DATA4, w ; call bcd_h ; addwf DATA4, f ; bcd3 movf DATA5, w ; call bcd_l ; addwf DATA5, f ; bcd4 movf DATA5, w ; call bcd_h ; addwf DATA5, f ; bcd5 movf DATA6, w ; call bcd_l ; addwf DATA6, f ; bcd6 movf DATA6, w ; call bcd_h ; addwf DATA6, f ; ; bcd_s rlf DATA1, f ; rlf DATA2, f ; rlf DATA3, f ; rlf DATA4, f ; rlf DATA5, f ; rlf DATA6, f ; bcf DATA4, 0 ; btfsc DATA3, 4 ; bsf DATA4, 0 ; decfsz COUNT1, f ; goto bcd1 ; ; ;-----преобразование разрядов индикатора----- clrf COUNT2 ; end_bcd call z1010 ;\ call z1010 ; |замена нулей на 1010 call z1010 ; | call z1010 ; | call z1010 ; | call z1010 ;/ ;\если режим калибровки btfsc GEN ; } генератора, то не return ;/ переставлять символы movlw b'10110000' ;\символ "F" справа movwf DEC910 ;/ на индикаторе btfsc KV_UKV ;\определить режим goto R_KV ;/ отображения R_UKV swapf DEC56, w ;\ andlw b'00001111' ; \ movwf DEC78 ; | movlw b'00001111' ; |перествавить местами andwf DEC56, f ; |разряды индикатора swapf DEC56, f ; |для УКВ режима swapf DEC34, w ; | было: " XXXXXX" andlw b'00001111' ; |стало: " XXX XXX" addwf DEC56, f ; | movlw b'00001111' ; / andwf DEC34, f ;/ return ;закончить ; R_KV movf DEC56, w ;\ movwf DEC78 ; \ swapf DEC34, w ; | andlw b'00001111' ; | movwf DEC56 ; |переставить местами swapf DEC34, w ; |разряды индикатора andlw b'11110000' ; |для КВ режима movwf DEC34 ; | было: " XXXXXX" swapf DEC12, w ; |стало: " XX XXX X" andlw b'00001111' ; | addwf DEC34, f ; | movlw b'00001111' ; / andwf DEC12, f ;/ return ;закончить ; z1010 movlw d'4' ; movwf COUNT1 ; z10 rlf DATA4, f ; rlf DATA5, f ; rlf DATA6, f ; rlf DEC12, f ; rlf DEC34, f ; rlf DEC56, f ; decfsz COUNT1, f ; goto z10 ; movf DEC12, w ; andlw b'00001111' ; movlw b'00000000' ; btfsc STATUS, 2 ; movlw b'00001010' ; btfss STATUS, 2 ; bsf COUNT2, 0 ; btfss COUNT2, 0 ; movlw b'00000000' ; addwf DEC12, f ; return ; ; bcd_l andlw b'00001111' ; sublw b'00000100' ; btfsc 0x03, 0 ; retlw h'00' ; retlw h'03' ; ; bcd_h andlw b'11110000' ; sublw b'01001111' ; btfsc 0x03, 0 ; retlw h'00' ; retlw h'30' ; ;----ВЫВОД ТЕКУЩЕЙ ЧАСТОТЫ НА ИНДИКАТОР (8б)----- F_LCD movf FREQ_L, w ;запомнить последнее movwf TEMP_F ; значение частоты movf FREQ_L, w ;\ movwf DATA1 ; \ movf FREQ_M, w ; | переслать FREQ в DATA movwf DATA2 ; / movf FREQ_H, w ;/ movwf DATA3 ; call BCD ;преобразование Bin в Dec goto LCD ;вывести на индик. и вернуться ;-----ВЫВОД НА ИНДИКАТОР (600цикл. 28б)----- LCD movlw MAS_LCD ;\выводы в состояние "0" andwf 0x06, f ;/ bsf STATUS, 5 ;банк1 bsf 0x81, 7 ;отключить подтяг. резисторы movlw d'40' ;\цикл вывода битов movwf COUNT1 ;/ (40 бит = 10 разрядов) ; out_i btfsc DEC910, 7 ;\ установка DATA в "1" bsf LCD_D ;/ btfss DEC910, 7 ;\ установка DATA в "0" bcf LCD_D ;/ rlf DEC12, f ;сдвиг < bsf LCD_C ;(CLK в "1") rlf DEC34, f ;сдвиг < rlf DEC56, f ;сдвиг < rlf DEC78, f ;сдвиг < rlf DEC910, f ;сдвиг < bcf LCD_C ;запись бита (CLK в "0") decfsz COUNT1, f ;декремент цикла или закончить goto out_i ; bcf LCD_D ;DATA в "0" rlf DEC12, f ;сдвиг < rlf DEC34, f ;сдвиг < bcf 0x81, 7 ;включить подтяг. резисторы rlf DEC56, f ;сдвиг < rlf DEC78, f ;сдвиг < rlf DEC910, f ;сдвиг < bcf STATUS, 5 ;банк0 return ;вернуться ;-----СОХРАНЕНИЕ КАЛИБРОВОЧНОЙ КОНСТАНТЫ ВО FLASH----- SAVE_CG movlw ADR_CG ;\установить адрес movwf EEADR ;/ movf GENER, w ;\установить данные movwf EEDATA ;/ goto SAVE ;записать и вернуться ;-----ЗАГРУЗКА КАЛИБРВОЧНОЙ КОНСТАНТЫ ИЗ FLASH----- LOAD_CG movlw ADR_CG ;\установить адрес movwf EEADR ;/ call LOAD ;загрузить данные movwf GENER ;переслать в GENER return ;вернуться ;-----СОХРАНЕНИЕ СЛОВА СОСТОЯНИЯ ВО FLASH----- SAVE_SO movlw ADR_SO ;\установить адрес movwf EEADR ;/ movf SOST, w ;\ andlw b'00001111' ; }установить данные movwf EEDATA ;/ goto SAVE ;записать и вернуться ;-----ЗАГРУЗКА СЛОВА СОСТОЯНИЯ ИЗ FLASH----- LOAD_SO movlw ADR_SO ;\установить адрес movwf EEADR ;/ call LOAD ;загрузить данные andlw b'00001111' ; movwf SOST ;переслать в SOST return ;вернуться ;-----СОХРАНЕНИЕ ТЕКУЩЕГО ДИАПАЗОНА ВО FLASH---- SAVE_DP movwf EEDATA ;установить данные SV_DP movlw ADR_DP ;\ установить адрес movwf EEADR ;/ goto SAVE ;записать и вернуться ;-----ЗАГРУЗКА ДИАПАЗОНА ИЗ FLASH----- LOAD_DP movlw ADR_DP ;\ установить адрес movwf EEADR ;/ goto LOAD ;загрузить данные ;-----ЗАГРУЗКА МАСКИ ОПЕРАЦИЙ С ПЧ ДЛЯ ДИАПАЗОНОВ----- LOAD_MS movlw ADR_MS ;\ установить адрес movwf EEADR ;/ старшего байта во FLASH call LOAD ;\загрузить старший байт movwf COUNT2 ;/ incf EEADR, f ;установ. адрес младш. байта call LOAD ;\ загрузить младший байт movwf COUNT1 ;/ return ;вернуться ;-----ЗАГРУЗКА ПРОМЕЖУТОЧНОЙ ЧАСТОТЫ ИЗ FLASH (10б)----- LOAD_PR clrf EEADR ; установить адрес во FLASH call LOAD ;\ считать старший байт movwf DATA6 ;/ incf EEADR, f ;\ call LOAD ; } считать средний байт movwf DATA5 ;/ incf EEADR, f ;\ call LOAD ; } считать младший байт movwf DATA4 ;/ return ; вернуться ;-----СОХРАНЕНИЕ ПРОМЕЖУТОЧНОЙ ЧАСТОТЫ ВО FLASH (12б)----- SAVE_PR clrf EEADR ;установ. адрес старш. байта movf DATA6, w ;\ movwf EEDATA ; }записать старший байт call SAVE ;/ incf EEADR, f ;установ. адрес средн. байта movf DATA5, w ;\ movwf EEDATA ; }записать средний байт call SAVE ;/ incf EEADR, f ;установ. адрес младш. байта movf DATA4, w ;\ movwf EEDATA ; }записать младший байт goto SAVE ;/ и вернуться ;-----СЧИТЫВАНИЕ БАЙТА ИЗ FLASH (8цикл. 7б)----- LOAD bsf STATUS, 5 ;банк1 bsf 0x88, 0 ;инициировать чтение c_load btfsc 0x88, 0 ;ждать окончания чтения goto c_load ; bcf STATUS, 5 ;банк0 movf EEDATA, w ; return ;возврат ;-----СОХРАНЕНИЕ БАЙТА ВО FLASH ( >10мс)----- SAVE bsf STATUS, 5 ;банк1 bsf 0x88, 2 ;wren on movlw 0x55 ; movwf 0x89 ; movlw 0xAA ; movwf 0x89 ; bsf 0x88, 1 ;инициировать запись c_save btfsc 0x88, 1 ;ждать окончания записи goto c_save ; bcf 0x88, 2 ;wren off bcf STATUS, 5 ;банк0 return ;возврат ;-----ФОРМИРОВАТЕЛЬ ПАУЗЫ (8б, 0.1сек)----- PAUSE; return bcf STATUS, 5 ;банк 0 movlw d'182' ; PAUS10 movwf COUNT2 ; PS movwf COUNT1 ; coun decfsz COUNT1, f ; goto coun ; decfsz COUNT2, f ; goto PS ; return ; end ;