Программа для МК
BSEG
ORG 0h
Cell_Tr: DBIT 1
DSEG
ORG 30h
Fr_low: DS 1
Fr_high: DS 1
Fase_low: DS 1
Fase_high: DS 1
Contr_sum: DS 1
CSEG
ORG 0h
Jmp On_Reset:
ORG 3h
Jmp Freq
ORG 0Bh
Reti
ORG 13h
Jmp Fase
ORG 1Bh
Reti
ORG 23h
Reti
ORG 40h
On_Reset :
Mov IE, #0 ; запрет всех прерываний
Mov Sp, #40h ; установка вершины стека
Mov IP, #0 ; все приоритеты прерываний одинаковы
Mov TCON,#0 ; внешние прерывания вызываются по низкому уровню
; на входах INT0,INT1
Mov TMOD,#00100000B ; таймер/счетчик Т1 работает в режиме 8-битного с
; таймера c автоперезагрузкой
Mov SCON,#11001100B ; 8-битовый приемопередатчик + бит паритета
Mov PCON,#10000000B ; удвоенная скорость передачи данных (SMOD=1)
Mov A, #243 ; настройка скорости последовательного интерфейса
Mov TH1, A ; 4800 бод/с
Setb TR1 ; запуск таймера T1
Mov DPTR, #0 ;
Mov IE, #10000001B ; разрешение прерываний от INT0 измерение частоты
Mov R0, #100 ; проверка правильности работы фазометра
Next_wait: ; при разрешенном прерывании
Acall Del_10 ; каждые 10 мс проверяется содержимое DPL
Mov A, R0 ;
Mov R1, A ;
Fr_beat:
NOP
Djnz R1, Fr_beat ; этот участок кода нужен для обнаружения частот
Mov A, DPL ; с периодом кратным 10 мс
Jnz Work ; если в DPL не ноль то фазометр работает нормально
Djnz R0, Next_wait ; иначе снова проверять
Clr EA ; запрет прерываний
Clr Cell_tr ; сбросить флаг работоспособности
Rjmp Send_error
Work:
Setb Cell_tr ; установить флаг работоспособности
Send_error:
Acall Get_COM ; ждать сообщения от ПК
Mov Acc.0, Cell_tr
Acall Transmit_COM ; послать сообщение ПК о работоспособности
Jb Cell_tr, To_do ; если фазометр работает, то продолжать работу
Ret ; иначе конец программы
To_do:
Acall Get_COM ; получить количество измерений
Mov R1, A
Acall Get_COM ; получить период измерений
Mov R5, A
Clr A
Mov Contr_sum, A ; обнуляем контрольную сумму
Next_measure:
Mov DPTR, #0 ; померять частоту
Mov IE, #10000001B ; разрешение прерываний от INT0 измерение частоты
Jnb IE0, $
Jb IE0, $
Clr EA
Mov A, DPH
Acall Transmit_COM ; передача ПК
Mov Fr_high, A ; сохранить старший байт
Mov A, DPL
Acall Transmit_COM ; передача ПК
Mov Fr_low, A ; сохранить младший байт
Mov A, Fr_high
Subb A, #36h
Jnc Meas_MK ; если DPH > 36h, то фазу меряет MK
Mov A, Fr_high
Subb A, #1Bh ; если DPH > 1Bh, то фазу меряет таймер с
Jnc Meas_T4 ; предделением частоты на 4
Mov A, Fr_high
Subb A, #0Dh ; если DPH > Dh, то фазу меряет таймер с предделением
Jnc Meas_T2 ; частоты на 2
Mov A, Fr_low
Subb A, #06h ; если DPL > 6, то фазу меряет таймер без предделения
Jnc Meas_T ; частоты, иначе таймер работает на
; максимальной частоте 60 МГц
Acall First_reset ; начальный сброс генератора
Mov A, #1 ; код команды записи в регистр DIV
Acall Write_Byte ; запись в генератор
Mov A, #00110010В ; загрузка 8 бит константы для задания частоты
; генератора
Acall Write_Byte ; запись в генератор
Acall Write_0 ; 9-ый бит
Ajmp Meas_G
Meas_T:
Mov R2, Fr_low ; вычисление
Mov R3, Fr_high
Mov R1, #4
Acall Dividing
Mov A, R2
Mov B, #75
MUL AB
Mov R2, A
Mov A, B
Mov R3, A
Mov R1, #5
Acall Dividing
Dec R2
Mov A, R3
Jnc Meas_G
Dec A
Mov R3, A
Acall First_reset ; начальный сброс
Mov A, #1 ; код команды записи в регистр DIV
Acall Write_Byte ; запись в генератор
Mov A, #00110100В ; загрузка 8 бит константы для задания частоты
; генератора
Acall Write_Byte ; запись в генератор
Acall Write_0 ; 9-ый бит
Ljmp Meas_G
Meas_T2:
Mov R2, Fr_low ; вычисление
Mov R3, Fr_high
Mov R1, #5
Acall Dividing
Mov A, R2
Mov B, #75
MUL AB
Mov R2, A
Mov A, B
Mov R3, A
Mov R1, #5
Acall Dividing
Acall First_reset ; начальный сброс
Mov A, #1 ; код команды записи в регистр DIV
Acall Write_Byte ; запись в генератор
Mov A, #00111000В ; загрузка 8 бит константы для задания частоты
; генератора
Acall Write_Byte ; запись в генератор
Acall Write_0 ; 9-ый бит
Ljmp Meas_G
Meas_T4:
Mov R2, Fr_low ; вычисление
Mov R3, Fr_high
Mov R1, #6
Acall Dividing
Mov A, R2
Mov B, #75
MUL AB
Mov R2, A
Mov A, B
Mov R3, A
Mov R1, #5
Acall Dividing
Acall First_reset ; начальный сброс
Mov A, #1 ; код команды записи в регистр DIV
Acall Write_Byte ; запись в генератор
Mov A, #00110000В ; загрузка 8 бит константы для задания частоты
; генератора
Acall Write_Byte ; запись в генератор
Acall Write_0 ; 9-ый бит
Meas_G:
Mov A, #2 ; код команды записи в программный делитель
Acall Write_Byte ; запись в генератор
Mov A, R2 ; младшие 8 бит предделителя
Acall Write_Byte ; запись в генератор
Mov A, R3 ; старший бит
Jb Acc.0, Wr1
Acall Write_0 ; запись в генератор 0
Ljmp St_m
Wr_1:
Acall Write_1 ; запись в генератор 1
St_m:
Acall First_reset ; начало работы генератора после программирования
Clr P0.1 ; сброс счетчиков
Jnb IE1, $ ; ждем пока не возникнет прерывания от изм. фазы
Setb P0.1 ; разрешение счета счетчиков
Jb IE1, $ ; ждем пока не завершиться прерывания от изм. фазы
Mov A, P1 ; считываем младший байт результата
Mov Fase_low, A
Mov A, P0 ; считываем старший байт результата
Anl A, #1111B ; обнуляем незначащие биты
Mov Fase_high, A
Ljmp Transm_fase
Meas_MK:
Mov DPTR, #0 ; обнуление счетчика
Mov IE, #10000100B ; пуск измерения фазы на частоте меньшей 28.6 Гц
Jnb IE1, $ ; с помощью аппаратных возможностей МК
Jb IE1, $
Clr EA
Mov A, DPН ; считывания старшего байта фазы
Mov Fase_high, A ; сохранение
Mov A, DPL ; считывания младшего байта фазы
Mov Fase_low, A ; сохранение
Transm_fase:
Mov A, Fase_high
Acall Transmit_COM ; передача ПК
Mov A, Fase_low
Acall Transmit_COM ; передача ПК
Acall Del_c ; задаем период измерения
Djnz R1, Next_measure ; следующее измерение
Mov A, Contr_sum ; передача контрольной суммы
Acall Transmit_COM
Ljmp To_do
ret
; подпрограмма начального сброса генератора
First_reset:
Clr I/O
Mov R0, #139
Acall Del_any
Setb I/O
Mov R0, #12
Acall Del_any
Jnb I/O, Rst3
Mov A, #1
Ret
Rst3:
Mov R0, #99
Acall Del_any
Jb I/O, Rst5
Mov A, #2
Ret
Rst5:
Mov A, #0
Ret
; подпрограмма записи бита #0 по однопроводному интерфейсу
Write_0:
Clr I/O
Mov R0, #15
Acall Del_any
Setb I/O
Ret
; подпрограмма записи бита #1 по однопроводному интерфейсу
Write_1:
Clr I/O
Mov R0, #1
Acall Del_any
Setb I/O
Mov R0, #14
Acall Del_any
Ret
; подпрограмма записи байта по однопроводному интерфейсу
Write_Byte:
Clr I/O ; запрет прерывания
Mov R1, #8 ; 8 бит
Wb1:
Rrc A ; А0>С
Jc Wb2 ;
Acall Write_0 ;
Jmp Wb3
Wb2:
Acall Write_1 ;
Djnz R1, Wb1 ;
Setb EA ;
Ret
; прием байта по COM-порту в аккумулятор
Get_COM:
Jnb RI, Get_COM
Mov A, SBUF
Clr RI
Ret
; передача байта по COM-порту через аккумулятор
Transmit_COM:
Mov SBUF, A
SEND:
Jnb TI, SEND
Clr TI
Push A ; контроль правильности передачи данных
Mov A, Contr_sum ; поблочным суммированием
Pop R4
Add A, R4
Mov Contr_sum, A
Ret
; задержка 5мкс
Del_5:
NOP
Ret
; подпрограмма задержки, параметр R0, задержка=5*R0 мкс
Del_Any:
Next_del:
Acall Del_5
Djnz R0, Next_del
Ret
; подпрограмма задержки на 10 мс
Del_10:
Push R1
Push R0
Mov R1, #10
To_next:
Mov R0, #199
Acall Del_any
Djnz R1, To_next
Pop R0
Pop R1
Ret
; подпрограмма задержки на R5 с
Del_c:
Mov A, R5
Mov R7, A
Del_sec:
Clr C
Mov R6, #100
Next_1c:
Acall Del_10
Dec R6
Jnc Next_1c
Mov R1, #10
Dec R7
Jnc Del_sec
Ret
; подпрограмма деления на 2n двухбайтового числа R3:R2 сдвигом n=R1
Dividing:
Clr C
Mov A, R3
Rrc A
Mov R3, A
Mov A, R2
Rr A
Mov R2, A
Djnz R0, Dividing
ret
; подпрограммы обработки прерываний
Freq:
Inc DPTR
reti
Fase:
Inc DPTR
NOP
NOP
NOP
NOP
NOP
reti
Описание алгоритма программы для ПК
Программа, которая будет выполняться ПК должна осуществить следующие действия:
1) определить у пользователя параметры измерения фазы;
2) инициировать начало работы фазометра;
3) считать сообщение о исправности фазометра;
4) в случае если он исправен послать сообщение о параметрах измерения фазы;
5) считать числа соответствующие фазе и частоте;
6) преобразовать частоту в герцы, а фазу в радианы и сохранить;
7) в конце измерения вывести на экран среднее значение фазы и частоты;
8) повторить все начиная с пункта 1.
Рис.6. . Блок-схема алгоритма программы для ПК