Genadi Zawidowski
06.07.2006, 18:16
ftp://ftp.radio.ru/pub/2006/06/sintez10.zip
Да удалит мое сообщение модератор...
;Программа для однодиапазонного синтезатора трансивера микросхема LM7001
;диапазон частот 1.8...16 мГц с шагом 50 Гц.
; версия от 25.11.2005 г
.include "1200def.inc"
.def hertzif = r1
.def per_delta = r2
.def pered_l = r3
.def pered_h = r4
.def worktx_l = r5
.def worktx_h = r6
.def delta_tx = r7
.def flag_reg = r8
.def if_l = r9
.def if_h= r10
.def number = r11
.def ind_l = r12
.def ind_m = r13
.def ind_h = r14
.def delta = r15
.def fl_l = r16
.def fl_h =r17
.def work_l =r18
.def work_h =r19
.def temp =r20
.def temp1 =r21
.def valc = r22
.def loop = r23
.def hertz = r24
.def mult_l =r25
.def mult_m = r26
.def mult_h = r27
.def fm_h = r28
.def fm_l = r29
.def temp16_l = r30
.def temp16_h = r31
.equ flag_sp = 0
.equ zero = 3
.equ plus = 2
.equ one = 1
.equ min = 0
.equ att_sav = 7
;PORTb
.equ DAC1 =0 ;out
.equ DAC2 =1;out
.equ DAC3 =2;out
.equ DAC4 =3;out
.equ RIT =4;in
.equ speed =5;in
.equ SK =6;out
.equ DI =7;out
;.equ TX =6 ; TX input, in
;PORTD
.equ UP =0;in
.equ DN =1;in
.equ DATA = 2 ;out
.equ CL =3;out
.equ CE =4;out
.equ plusfc =5; + - ПЧ, "0" - минус ПЧ, "1" - плюс ПЧ
.equ DAC0 =6;out
.cseg
.org 0
;******************* ******************** *************
;***************наст ройка портов************** ******
;******************* ******************** ************
ldi temp, 0b00110000
out PORTB, temp
ldi temp, 0b11001111
out DDRB, temp ;
ldi temp, 0b10100011
out PORTD, temp
ldi temp, 0b01011100
out DDRD, temp ;
clr delta;
;******************* ******************** ******************** ****
;********начальная пауза для инициализации индикатора********** *
;******************* ******************** ******************** ****
cold_start:ldi temp, 0x50
rcall pause_ro
;******************* ******************** ******************** ***
;********начальные настройки*********** ******************** ****
;******************* ******************** ******************** ***
ldi valc, 0x01
clr number
clr delta
;******************* ******************** *********
;переход к ручному вводу ПЧ
;******************* ******************** *********
sbic PINB, RIT
rjmp hot_start
ritotp1:ldi temp, 0x02 ;пауза для уменьшения дребезга
rcall pause_ro
sbis PINB, RIT ;если кнопка ещё нажата, ждём отпускания
rjmp ritotp1
ldi temp, 0xF0 ;отображаем "-" слева на индикаторе
mov number, temp
ldi temp, if_hz
rcall EERead
mov hertzif, temp
ldi temp,if_freq ; загружаем значение из первой ячейки памяти в рабочую
rcall EERead
mov work_h, temp
ldi temp, if_freq +1
rcall EERead
mov work_l, temp
initial1:rcall display
;******************* ********************
;***Опрос клавиш************** ********
;******************* ******************
bigloop1:
sbis PINB, RIT ;если не нажато РИТ
rjmp savdata ;выскакиваем
sbic PIND,UP
rjmp up_ust1
sbic PIND,DN
rjmp dn_ust1
sbrc valc, zero
rjmp bigloop1
sbrc valc, min
rjmp rout11
sbrc valc, plus
rjmp rout21
rjmp bigloop1
;***Обработка опроса клавиш ******************** ****
up_ust1:sbic PIND,DN
rjmp dbl_one1
; это состояние, когда up=1, dn=0
sbrc valc,plus
rjmp bigloop1
;какое состояние было раньше?
sbrs valc,zero; если раньше был ноль
rjmp nxt_val1
ldi valc, 0b00000100
rcall add_one ; увеличиваем на 1
rjmp initial1
nxt_val1:sbrs valc, one ; если раньше был 1
rjmp bigloop1
ldi valc,0b000000100
rcall sub_one ;уменьшаем на 1
rjmp initial1
dbl_one1:sbrc valc,one ; если оне =0, то валкодер не вращался
rjmp bigloop1 ; возвращаемся
sbrs valc,plus;проверяем, что было раньше
rjmp nxt_val21 ; если это не +1, перех
ldi valc, 0b00000010 ; в противном случае
rcall add_one
rjmp initial1
nxt_val21:sbrs valc,min
rjmp bigloop1
ldi valc, 0b00000010
rcall sub_one
rjmp initial1
rout11:ldi valc,0b00001000
rcall add_one
rjmp initial1
rout21: ldi valc,0b00001000
rcall sub_one
rjmp initial1
dn_ust1:sbrc valc, min
rjmp bigloop1
sbrc valc, zero
rjmp rout31
sbrc valc, one
rjmp rout41
rjmp bigloop1
rout31: ldi valc,0b00000001
rcall sub_one
rjmp initial1
rout41: ldi valc,0b00000001
rcall add_one
rjmp initial1
;******************* ******************** ********
;запись информации в ЕЕПРОМ
;******************* ******************** ********
savdata:ldi temp, if_freq
mov temp1, work_h
rcall EEwrite
ldi temp,if_freq+1
mov temp1, work_l
rcall EEwrite
sbis PINB, RIT
ldi temp, if_hz
mov temp1, hertzif
ritotp2:ldi temp, 0x02 ;пауза для уменьшения дребезга
rcall pause_ro
sbis PINB, RIT ;если кнопка ещё нажата, ждём отпускания
rjmp ritotp2
ser temp
rcall vyvdig
rcall vyvdig
ser temp
rcall vyvdig
rcall vyvdig
ser temp
rcall vyvdig
rcall vyvdig
ser temp
rcall vyvdig
rcall vyvdig
ser temp
rcall vyvdig
rcall vyvdig
rjmp cold_start
;******************* *******
;начальная загрузка частотных границ и ПЧ из ЕЕПРОМ
;******************* *******
hot_start:ldi temp, fmin ;загружаем из памяти минимальную границу
rcall EERead
mov fl_h, temp
ldi temp, fmin + 1
rcall EERead
mov fl_l, temp
ldi temp, fmax ; загружаем максимальную границу
rcall EERead
mov fm_h, temp
ldi temp, fmax + 1
rcall EERead
mov fm_l, temp
ldi temp, if_freq ;загружаем частоту ПЧ
rcall EERead
mov if_h, temp
ldi temp, if_freq + 1
rcall EERead
mov if_l, temp
ldi temp, if_hz
rcall EERead
mov hertzif, temp
ldi temp,ch1 ; загружаем значение из первой ячейки памяти в рабочую
rcall EERead
mov work_h, temp
mov worktx_h, work_h
ldi temp, ch1 +1
rcall EERead
mov work_l, temp
mov worktx_l, work_l
initial:
rcall display
rcall syntez
;******************* ********************
;***Опрос клавиш************** ********
;******************* ******************
bigloop:
sbic PINB, RIT ;если не нажато RIT
rjmp no_rit ;выскакиваем
sbic PINB, speed ;если нажато, проверяем на нажатие speed
rjmp rit_rout; нажата только RIT-подпрограмма расстройки
rjmp tx_rout ;нажаты обе кнопки - передача
no_rit:sbic PIND,UP
rjmp up_ust
sbic PIND,DN
rjmp dn_ust
sbrc valc, zero
rjmp bigloop
sbrc valc, min
rjmp rout1
sbrc valc, plus
rjmp rout2
rjmp bigloop
;***Обработка опроса клавиш ******************** ****
up_ust:sbic PIND,DN
rjmp dbl_one
; это состояние, когда up=1, dn=0
sbrc valc,plus
rjmp bigloop
;какое состояние было раньше?
sbrs valc,zero; если раньше был ноль
rjmp nxt_val
ldi valc, 0b00000100
rcall add_one ; увеличиваем на 1
rjmp initial
nxt_val:sbrs valc, one ; если раньше был 1
rjmp bigloop
ldi valc,0b000000100
rcall sub_one ;уменьшаем на 1
rjmp initial
dbl_one:sbrc valc,one ; если оне =0, то валкодер не вращался
rjmp bigloop ; возвращаемся
sbrs valc,plus;проверяем, что было раньше
rjmp nxt_val2 ; если это не +1, перех
ldi valc, 0b00000010 ; в противном случае
rcall add_one
rjmp initial
nxt_val2:sbrs valc,min
rjmp bigloop
ldi valc, 0b00000010
rcall sub_one
rjmp initial
rout1:ldi valc,0b00001000
rcall add_one
rjmp initial
rout2: ldi valc,0b00001000
rcall sub_one
rjmp initial
dn_ust:sbrc valc, min
rjmp bigloop
sbrc valc, zero
rjmp rout3
sbrc valc, one
rjmp rout4
rjmp bigloop
rout3: ldi valc,0b00000001
rcall sub_one
rjmp initial
rout4: ldi valc,0b00000001
rcall add_one
rjmp initial
;****************уве личение частоты************* ********
add_one:
sbis PINB,speed
rjmp step_up
inc delta
ldi temp,0x14
cp delta, temp
brne end_add
clr delta
step_up: clr temp
clc
ldi temp, 0x01
add work_l, temp ; увеличить на 1 значение в рабочей ячейке
clr temp
adc work_h, temp ; если был перенос, увеличиваем на 1 старший разряд
cp fm_h, work_h ; достгло ло значение старшего разряда макс?
brne out_add ; нет-выход
cp fm_l, work_l ; если да, проверяем младший разряд
brsh out_add
mov work_h, fl_h ; дошло до конца - загружаем рабочую ячейку мин.
mov work_l, fl_l ; значением
end_add:sbrc flag_reg, flag_sp
ret
mov delta_tx, delta ; если не включена расстройка, частота передачи
mov worktx_h, work_h; равна частоте приёма
mov worktx_l, work_l
out_add:ret
;************понижен ие частоты************* ****************
sub_one:
sbis PINB, speed
rjmp step_dn
dec delta
ser temp
cp delta, temp
brne end_sub
ldi temp,0x13
mov delta, temp
step_dn:clr temp
clc
subi work_l, 0x01 ;уменьшаем на 1 младший байт
sbc work_h, temp ; если был перенос, уменьшаем старший байт
cp work_h, fl_h ; дошло до конца?
brne out_sub ; нет
cp work_l, fl_l ; дошло до конца?
brsh out_sub ; нет
mov work_h, fm_h ;если дошло, переписываем в рабочую ячейку
mov work_l, fm_l ;максимальное значение
end_sub:sbrc flag_reg, flag_sp
ret
mov delta_tx, delta
mov worktx_h, work_h
mov worktx_l, work_l
out_sub:ret
;******************* ******************** *******
;****************пер едача*************** *******
;******************* ******************** *******
tx_rout:mov pered_l, work_l ;заносим в рабочие регистры
mov pered_h, work_h ;частоту передачи
mov work_l, worktx_l ;частоту приёма сохраняем
mov work_h, worktx_h
mov per_delta, delta
mov delta, delta_tx
ldi temp, 0xB0 ;отображаем "Ф" слева на индикаторе
mov number, temp
rcall display
rcall syntez
tx_ret: ldi temp, 0x01 ;пауза для уменьшения дребезга
rcall pause_ro
sbis PINB, speed ;если одна из кнопок отпущена
sbic PINB, RIT
rjmp end_tx ;конец передачи
rjmp tx_ret ; передача продолжается
end_tx: mov worktx_l, work_l ;заносим в рабочие регистры
mov worktx_h, work_h ;частоту приёма
mov work_l, pered_l ;частоту передачи сохраняем
mov work_h, pered_h
mov delta_tx, delta
mov delta, per_delta
sbrs flag_reg, flag_sp ; был ли включён режим расстройки
rjmp del_num
ldi temp, 0xE0 ;если да, отображаем "Р"
mov number, temp
rjmp initial
del_num:clr number ;если нет - просто стираем символ на экране
rjmp initial
;******************* ******************** ********
;******************Р АССТРОЙКА*********** ********
;******************* ******************** ********
rit_rout: ldi temp, 0x02 ;пауза для уменьшения дребезга
rcall pause_ro
sbis PINB, RIT ;если кнопка ещё нажата, ждём отпускания
rjmp rit_rout
mov temp, flag_reg
sbrc temp, flag_sp ; если бит установлен,
rjmp res_rit ;сбрасываем
sbr temp, 0x01 ; если был сброшен, устанавливаем
ldi temp1, 0xE0
mov number, temp1 ;в левом знакоместе выводим "Р"
rjmp end_rit
res_rit:cbr temp, 0x01 ;сбрасываем бит
clr number ;больше не выводим "Р"
mov delta, delta_tx ;восстанавливаем старые значения
mov work_h, worktx_h
mov work_l, worktx_l
end_rit:mov flag_reg, temp
rjmp initial
;******************* ******************** *******
;******отображение на дисплее************* *****
;******************* ******************** ******
;************ преобразование частоты из 16-ричного вида в десятичный********** ****
display:
mov mult_l, work_l
mov mult_m, work_h
ldi temp16_l, 0x10 ;определяем количество десятков тысяч
ldi temp16_h, 0x27
rcall decdig
mov ind_h, temp
add ind_h, number ; добавляем крайний левый символ
ldi temp16_l, 0xE8 ;определяем количество тысяч
ldi temp16_h, 0x03
rcall decdig
cpi temp, 0x00
brne nextdig2
ldi temp, 0x0A
nextdig2:mov ind_m, temp
swap ind_m
ldi temp16_l, 0x64 ;определяем количество сотен
clr temp16_h
rcall decdig
cpi temp, 0x00
brne nextdig3
ldi temp, 0x0A
nextdig3:add ind_m, temp
ldi temp16_l, 0x0A ; определяе мколичество десятков
clr temp16_h
rcall decdig
cpi temp, 0x00
brne nextdig4
ldi temp, 0x0A
nextdig4:mov ind_l, temp ; в конце операции в ячейках инд содержится
swap ind_l ;десятичное значение рабочей частоты
cpi mult_l,0x00 ;нули заменены на А - для вывода на индикатор.
brne enddig
ldi mult_l,0x0A
enddig:add ind_l, mult_l
;преобразуем значение дельта в герцы
mov hertz, delta ; делим на 2
ror hertz
brcc zero_hz ;если разделилось без остатка,перех
ldi temp, 0x05 ;в противном случае - 5
rjmp next5
zero_hz: ldi temp,0x0A ;в крайней позиции записываем "А"
next5: cpi hertz, 0x00 ; если сотни гц = 0, меняем на А
brne next3
ldi hertz, 0x0A
next3:swap hertz
add hertz, temp
;******************* *вывод на дисплей************* ************
mov temp, ind_h
rcall vyvdig
rcall vyvdig
mov temp, ind_m
rcall vyvdig
mov ind_m, temp
ldi temp, 0xF0
rcall vyvdig
mov temp, ind_m
rcall vyvdig
mov temp, ind_l
rcall vyvdig
rcall vyvdig
ldi temp, 0xF0
rcall vyvdig
mov temp, hertz
rcall vyvdig
rcall vyvdig
;******************* *********
;***установка ЦАП************
;******************* *********
ldi temp, 0x0A
add delta, temp
sbrc delta, 0
rjmp hi0
cbi PORTD, DAC0
rjmp next11
hi0:sbi PORTD, DAC0
next11:sbrc delta, 1
rjmp hi1
cbi PORTB, DAC1
rjmp next12
hi1:sbi PORTB, DAC1
next12:sbrc delta,2
rjmp hi2
cbi PORTB, DAC2
rjmp next13
hi2:sbi PORTB, DAC2
next13:sbrc delta, 3
rjmp hi3
cbi PORTB, DAC3
rjmp next14
hi3:sbi PORTB, DAC3
next14:sbrc delta,4
rjmp hi4
cbi PORTB, DAC4
rjmp enddac
hi4:sbi PORTB, DAC4
enddac:sub delta, temp
ret
;*****ВВод информации в синтезатор********** ********
;B0=0, B1=0, B2=0, tb=0, R0=1, R1=1, R2=0, S=1
syntez:
mov temp16_l, work_l ; множимое - текущее значение частоты
mov temp16_h, work_h
sbis PINB, plusfc
rjmp minus_fc
add temp16_l,if_l ;добавляем ПЧ
adc temp16_h,if_h
rjmp end_fc
minus_fc:sub delta, hertzif
sub temp16_l, if_l
sbc temp16_h, if_h
;******цикл записи********
end_fc:cbi PORTD,DATA
sbi PORTD,CE
ldi loop, 0x08
mov temp,temp16_l
loop2:ror temp
brcs h_l
cbi PORTD, DATA
rjmp sync
h_l:sbi PORTD, DATA
sync:rcall pulse
dec loop
brne loop2
ldi loop, 0x08
mov temp, temp16_h
loop3:ror temp
brcs h_l1
cbi PORTD, DATA
rjmp sync1
h_l1:sbi PORTD, DATA
sync1:rcall pulse
dec loop
brne loop3
ldi loop, 0x08
ldi temp, 0B10110000
loop4:ror temp
brcs h_l2
cbi PORTD, DATA
rjmp sync2
h_l2:sbi PORTD, DATA
sync2:rcall pulse
dec loop
brne loop4
cbi PORTD, DATA ;CE
cbi PORTD, CE
ret
;***вывод цифры на индикатор***
vyvdig:
ldi loop,0x04
byte_c:rol temp
brcs h_level
cbi PORTB,DI
rjmp synhro
h_level:sbi PORTB,DI
synhro:sbi PORTB,SK
rcall long
cbi PORTB,SK
rcall long
dec loop
brne byte_c
rcall long
cbi PORTB, DI
ret
;******************* ******
; Запись в ЕЕПРОМ
;******************* *******
EEwrite: sbic EECR, EEWE
rjmp EEwrite
out EEAR, temp
out EEDR, temp1
sbi EECR, EEWE
ret
;******************* ****
; Чтение из памяти
;******************* ****
EEread: sbic EECR,EEWE
rjmp EERead
out EEAR,temp
sbi EECR,EERE
in temp,EEDR
ret
;******************* **
; пауза
;******************* **
pause_ro:
ser temp1
retu1:ser loop
retu2:dec loop
brne retu2
dec temp1
brne retu1
dec temp
brne pause_ro
ret
long:
ldi temp1, 0x02
retlong:dec temp1
brne retlong
ret
;******************* ******************** *******
;подпрограмма пересчёта НЕХ- десятичное число
;******************* ******************** *******
decdig:ldi temp,-1
minus:sub mult_l, temp16_l
sbc mult_m, temp16_h
inc temp
brsh minus
add mult_l, temp16_l
adc mult_m, temp16_h
ret
;******************* **
; синхроимпульс
;******************* **
pulse:
sbi PORTD, CL
ldi temp1,0x1F
zad1:dec temp1
brne zad1
cbi PORTD, CL
ldi temp1,0x1F
zad2:dec temp1
brne zad2
ret
.eseg
.org 0
fmin:
.db 0x07, 0x12 ;минимальная частота 1810 кГц
fmax:
.db 0x07, 0xCF ;максимальная частота 2000 кГц
ch1:
.db 0x07, 0x6C ; - начальное значение частоты - 1900 кГц
if_freq:
.db 0x22, 0x9E ; - частота ПЧ в кГц - по умолчанию 8862 кГц
if_hz:
.db 0x00 ; - дробная часть ПЧ - герцы, округл. до 50
;и делённые на 50/
.db "(c)Temerev25_11_2005"
Ну это не так страшно, это цена за простоту конструкции. Кстати , если на выход синтеза подключить простую цифровую шкалу, например на 16F84, то можно будет видеть точное значение частоты.
Тут посмотрел описание LM7001J: так там указано, что шаг сетки частот может быть 1, 5, 9, 10 и т.д. кгц, не сказано , что он может быть 1,5 кгц. А тогда при шаге 5 кгц, верхний предел получится: 16383*5 кгц=81 915 кгц. Тогда ГУН (при ПЧ=8,8мгц для 28-29,7 мгц) можно сделать на частоты 57,6-62,7 мгц, частоту ГУНа подавать на ногу 11 LM7001 напрямую, а на выход синтеза через делитель на 3. Тогда шаг синтезатора получится - 1,6666(6) кгц, а шаг ЦАПа - 83,333(3) гц. Не совсем хорошо, но работать должно. Чтобы сделать шаг 5 кгц, надо в куске программы-***ВВод информации в синтезатор**** переписать биты R0, R1, R2 в виде: R0=1, R1=1, R2=1. В связи с этим вопрос к UN7DAQ, вот я скажем внес изменения в программу на ассемблере, а как мне теперь переписать ее в кодах, для этого нужен сам ассемблер-транслятор процессора, который стоит в синтезаторе, где например вы его брали для своего ATmega8 и где взять для AT90S1200 ? Скачать с интернета- ?
Тут посмотрел схему синтезатора Темерева журнале Радио №12 за 2004год, стр.57, так может проще из него сделать синтез на все частоты чем на LM7001J ?
Powered by vBulletin® Version 4.1.12 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot