;============================================= ;Синтезатор 145 мгц ;А.Ю. Денисов Тамбов 1999 г. ;ПЧ=10700. WDT OFF. F_RC_osc=1.2 мГц. ; ;============================================= ;порты ; indf equ 00 ;указатель косвенной адресации tmr0 equ 01 ;таймер pcl equ 02 ;счетчик команд stat equ 03 ;регистр состояния status fsr equ 04 ;регистр косвенной адресации ; port_a equ 05 ;порт А port_b equ 06 ;порт В ; ;============================================= ;регистры ; step equ 0E ;шаг перестройки count equ 0F ;счетчик count1 equ 10 ;счетчик rotate equ 11 ;ротация DATA cross equ 12 ;признак ретранслятора ; H_mulplr equ 13 ;Старший байт 16-битного множимого L_mulplr equ 14 ;Младший байт 16-битного множимого mulcnd equ 15 ;8-битный множитель ; R0 equ 16 ; R1 equ 17 ;на R2 equ 18 ;индикаторе ; H_byte equ 19 ; буфер M_byte equ 1A ; преобразования L_byte equ 1B ; ; rxhi equ 1C ;делитель rxlo equ 1D ;приема ; txhi equ 1E ;делитель txlo equ 1F ;передачи ; ;============================================= ;Макросы ; jnz macro metka btfss stat,2 goto metka endm ; jz macro metka btfsc stat,2 goto metka endm ; jnc macro metka btfss stat,0 goto metka endm ; jc macro metka btfsc stat,0 goto metka endm ; ;============================================= list p=16F84 __CONFIG 03FF3H ;============================================= ;************ SUBROUTINES ******************** ;============================================= ; org 0 goto start ; ;Начальная инициализация init movlw 10 ;задержка movwf count1 ;для init2 ;инициализации movlw 0xFF ;индикатора movwf count ;HT1610 init1 ; decfsz count,f ; goto init1 ; ; decfsz count1,f ; goto init2 ; init3 movlw 0fh ; movwf fsr ; clear ;начальное clrf indf ;обнуление incf fsr,f ;служебных btfss fsr,5 ;ячеек goto clear ; ; clrf fsr ;выбор 0 банка ; movlw 0x71 ; movwf txhi ;передача movlw 0x84 ;145.300/5 movwf txlo ; ; movlw 0x69 ; movwf rxhi ;прием movlw 0x28 ;(145.300-10.7)/5 movwf rxlo ; ; retlw 0 ;выход из п\программы. ; ;============================================= ;Выдать байт на индикатор displ movwf rotate ;байт из W в файл rotate clrf count ;загрузить 8 bsf count,3 ; в счетчик бит. bcf stat,0 ;сброс cary displ1 clrf stat rlf rotate,f ;сдвиг rotate влево через C btfsc stat,0 ;если Cary=0 skip bsf port_b,5 ;установить DATA=1 btfss stat,0 ;если Сary=1 skip bcf port_b,5 ;уст. DATA=0 nop bsf port_b,4 ;CLK=1 _- nop bcf port_b,4 ; =0 -_ тактовый импульс decfsz count,f ;проверить счетчик бит. goto displ1 ;не равен 0. Следующий бит. ; retlw 0 ;выход из п\программы. ; ;============================================= ;Вкл/откл режима ретранслятора retrans movf cross,f ;ретранслятор включен? jnz init3 ;да, нужно выключить movlw 0xE0 ;иначе нужно movwf cross ;включить ; movlw 0x71 ; movwf txhi ;передача movlw 0x6B ;145.175/5 movwf txlo ; ; movlw 0x69 ; movwf rxhi ;прием movlw 0x87 ;(145.775-10.7)/5 movwf rxlo ; ; retlw 0 ;выход из п\программы. ; ;============================================= ;Плюс 25 килогерц plus25 movf step,w addwf rxlo,f jnc pl1 incf rxhi,f pl1 movf step,w addwf txlo,f jnc pl2 incf txhi,f pl2 retlw 0 ;выход из п\программы. ; ;============================================= ;Минус 25 килогерц minus25 movf step,w subwf rxlo,f jc min1 decf rxhi,f min1 movf step,w subwf txlo,f jc min2 decf txhi,f min2 retlw 0 ;выход из п\программы. ; ;============================================= ;Плюс 100 килогерц plus100 movf step,w movwf count bcf stat,0 rlf count,f rlf count,w addwf rxlo,f jnc pl21 incf rxhi,f pl21 movf step,w movwf count bcf stat,0 rlf count,f rlf count,w addwf txlo,f jnc pl22 incf txhi,f pl22 retlw 0 ;выход из п\программы. ; ;============================================= ;Минус 100 килогерц minus100 movf step,w movwf count bcf stat,0 rlf count,f rlf count,w subwf rxlo,f jc min21 decf rxhi,f min21 movf step,w movwf count bcf stat,0 rlf count,f rlf count,w subwf txlo,f jc min22 decf txhi,f min22 retlw 0 ;выход из п\программы. ; ;============================================= ;Подтверждение нажатия клавиши sound movlw .50 movwf count sound2 bsf port_b,6 ;_i- ; ;задержка -------------------------------- movlw .10 movwf count1 sound1 decfsz count1,1 ;задержка ~2ms goto sound1 ; bcf port_b,6 ; -i_ ; ;задержка -------------------------------- movlw .10 movwf count1 sound11 decfsz count1,1 ;задержка ~2ms goto sound11 ; decfsz count,1 goto sound2 ; retlw 0 ;выход из п\программы. ;============================================= ;Установить частоту в 1508PL1 setfreq movlw 4 ;выдать в 1508ПЛ1 call send ;1й байт=4 (делитель на 2000) movfw count1 movwf fsr movfw 0 call send ; incf count1,f movfw count1 movwf fsr movfw 0 call send ; strob bsf port_a,2 ;1 _- nop bcf port_a,2 ;0 -_ ; retlw 0 ;выход из п\программы. ; ;============================================= ;Выдать байт из rotate последовательно в 1508PL1 send movwf rotate ;байт из W в файл rotate clrf count ;загрузить 8 bsf count,3 ; в счетчик бит. bcf 3,0 ;сброс cary next rlf rotate,f ;сдвиг rotate влево через C btfsc 3,0 ;если Cary=0 skip bsf port_a,0 ;установить DATA=1 btfss 3,0 ;если Сary=1 skip bcf port_a,0 ;уст. DATA=0 nop bsf port_a,1 ;CLK=1 _- nop bcf port_a,1 ; =0 -_ тактовый импульс decfsz count,1 ;проверить счетчик бит. goto next ;не равен 0. Следующий бит. retlw 0 ;выход из п\программы. ; ;============================================= ;Преобразование bin to BCD ; b2_bcd bcf stat,0 ; clear the carry bit movlw .24 movwf count clrf R0 clrf R1 clrf R2 loop16 rlf L_byte,f rlf M_byte,f rlf H_byte,f rlf R2,f rlf R1,f rlf R0,f ; decfsz count,f goto adjDEC ; ; заменяем нули на 0xA для LCD индикатора movlw 0x0F andwf R2,0 jnz next1 movlw 0x0A iorwf R2,f next1 movlw 0xF0 andwf R2,0 jnz next2 movlw 0xA0 iorwf R2,f next2 movlw 0x0F andwf R1,0 jnz next3 movlw 0x0A iorwf R1,f next3 retlw 0 ; adjDEC movlw R2 movwf fsr call adjBCD ; movlw R1 movwf fsr call adjBCD ; movlw R0 movwf fsr call adjBCD ; goto loop16 ; adjBCD movlw 3 addwf 0,W movwf count1 btfsc count1,3 ; test if result > 7 movwf 0 movlw 30 addwf 0,W movwf count1 btfsc count1,7 ; test if result > 7 movwf 0 ; save as MSD ; retlw 0 ; ;============================================= ; Умножение 16-битного числа на 8-битное ; m16x8 clrf H_byte clrf M_byte clrf L_byte movlw .16 movwf count movf mulcnd,w bcf stat,0 ; Clear the carry bit in the loop ; status Reg. rrf H_mulplr,f rrf L_mulplr,f btfsc stat,0 addwf H_byte,f rrf H_byte,f rrf M_byte,f rrf L_byte,f decfsz count,f goto loop ; retlw 0 ; ;============================================= ; Изменение шага перестройки 5 <-> 25 килогерц ; newstep movlw 4 xorwf step,f goto hotstart ; ;============================================= ;************ MAIN PROGRAM ******************* ;============================================= start bsf stat,5 ;для 16F84 movlw 0 movwf 01h movlw 8 movwf port_a movlw 08Fh movwf port_b bcf stat,5 call init ;инициализация movlw 5 movwf step ; goto hotstart ; ;опрос клавиш begin movf port_b,w ;из port_b в W andlw 8f ;маскируем выходные порты xorlw 0f ;есть нажатая клавиша? btfsc stat,2 ; goto begin movlw 10 ; movwf count1 ; loop2 ; movlw 0xFF ; movwf count ; loop1 ; decfsz count,f ;задержка (антидребезг) goto loop1 ; ; decfsz count1,f ; goto loop2 ; ; ; еще раз смотрим нажатие клавиши movf port_b,w ;из port_b в W andlw 8f ;маскируем выходные порты xorlw 0f ;есть нажатая клавиша? btfsc stat,2 ; goto begin ; ; обработка нажатия клавиши ---------------------- movf port_b,w ;читаем из port_b в W movwf rotate ;запоминаем в rotate andlw 0x03 jz retrans1 movf rotate,w andlw 0x0C jz newstep rlf rotate,w jc transmit rrf rotate,f jnc pl25 rrf rotate,f jnc mn25 rrf rotate,f jnc pl100 call minus100 ;минус 100 кгц hotstart call sound ;писк movlw rxhi ;установка относительной movwf count1 ;адресации call setfreq ;установка частоты ; прибавим ПЧ для вывода на индикатор ; movlw 0x5C ;загружаем первое слагаемое movwf L_mulplr ;равное 10700/5 movlw 0x08 movwf H_mulplr ; movf rxlo,w ;второе слагаемое равное addwf L_mulplr,f ;(частота - ПЧ)/5 jnc hot1 incf H_mulplr,f hot1 movf rxhi,w addwf H_mulplr,f hot2 movlw .5 ;умножаем на 25 movwf mulcnd call m16x8 call b2_bcd ;переводим в дв.-десятичный вид ; с исправлениями для индикатора HT1610 ; ; и выводим на индикатор movf cross,w ;признак ретранслятора call displ ; movlw 0 ; пробел call displ ; movf R0,w ; частота call displ ; movf R1,w ; call displ ; movf R2,w ; call displ ; ; keyoff ;ждем отжатие клавиши movf port_b,w ;из port_b в W andlw 8f ;маскируем выходные порты xorlw 0f ;есть нажатая клавиша? jnz keyoff ; movlw 10 movf count1,f koff2 movlw 0xFF movf count,f koff1 decfsz count,f goto koff1 decfsz count1,f goto koff2 goto begin ; retrans1 ;ретранслятор on/off call retrans goto hotstart ; pl25 ;плюс 25 кгц call plus25 goto hotstart ; mn25 ;минус 25 кгц call minus25 goto hotstart ; pl100 ;плюс 100 кгц call plus100 goto hotstart ; transmit movlw txhi ;установка относительной movwf count1 ;адресации call setfreq ;установка частоты ; movf txlo,w ;переносим множимое movwf L_mulplr movf txhi,w movwf H_mulplr ; movlw .5 ;умножаем на 25 movwf mulcnd call m16x8 call b2_bcd ;переводим в дв.-десятичный вид ; с исправлениями для индикатора HT1610 ; и выводим на индикатор movf cross,w ;признак ретранслятора call displ ; movlw 0 ; пробел call displ ; movf R0,w ; частота call displ movf R1,w call displ movf R2,w call displ ; keyoff1 ;ждем отжатие клавиши movf port_b,w ;из port_b в W andlw 8f ;маскируем выходные порты xorlw 0f ;есть нажатая клавиша? btfss stat,2 ; goto keyoff1 movlw 10 movf count1,f koff12 movlw 0xFF movf count,f koff11 decfsz count,f goto koff11 decfsz count1,f goto koff12 ; goto hotstart end