MovA, P1 ; считываем младший байт результата
MovFase_low, A
MovA, P0 ; считываем старший байт результата
AnlA, #1111B ; обнуляем незначащие биты
Mov Fase_high, A
Ljmp Transm_fase
Meas_MK:
Mov DPTR, #0 ; обнулениесчетчика
MovIE, #10000100B ; пуск измерения фазы на частоте меньшей 28.6 Гц
JnbIE1, $ ; с помощью аппаратных возможностей МК
JbIE1, $
ClrEA
MovA, DPН ; считывания старшего байта фазы
MovFase_high, A ; сохранение
MovA, DPL ; считывания младшего байта фазы
Mov Fase_low, A ; сохранение
Transm_fase:
Mov A, Fase_high
Acall Transmit_COM ; передачаПК
Mov A, Fase_low
Acall Transmit_COM ; передачаПК
AcallDel_c ; задаем период измерения
DjnzR1, Next_measure ; следующее измерение
MovA, 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:
ClrI/O ; запрет прерывания
MovR1, #8 ; 8 бит
Wb1:
Rrc A ; А0→С
Jc Wb2 ;
Acall Write_0 ;
Jmp Wb3
Wb2:
Acall Write_1 ;
Djnz R1, Wb1 ;
SetbEA ;
Ret
; прием байта по COM-порту в аккумулятор
Get_COM:
Jnb RI, Get_COM
Mov A, SBUF
Clr RI
Ret
; передача байта по COM-порту через аккумулятор
Transmit_COM:
Mov SBUF, A
SEND:
JnbTI, SEND
ClrTI
PushA ; контроль правильности передачи данных
MovA, 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
DjnzR0, 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
PopR1
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. . Блок-схема алгоритма программы для ПК
Программа для ПК
usescrt;
var i,k,z,contr,l,ms:Byte;
Base : word ;
Value : byte;
t :Boolean;
fase,freaquency:integer;
fase_r,freaquency_r,divider:real;
data:array[1..100,1..2]of real absolute $6B00:$0000;
Procedure OpenCom(Base:word ; Baudrate:word ; Config :byte);
begin
while Port[Base+5] and $60 <> $60 do;
Port[Base+3] := $80;
Port[Base+1] := BaudRate shr 8;
Port[Base+0] := BaudRate and $FF;
Port[Base+3] := Config;
Port[Base+4] := 0;
Port[Base+1] := 0;
end;
Procedure send_char(Base : word ; Value : byte);
begin
while ((Port[Base+5] and $20) = 0) do ;
Port[Base] := Byte(Value);
end;
Function get_char( Base : word ) : Boolean;
var status : word;
begin
Status := Port[Base + 5];
if ((Status and $1E) <> 0) or ((Status and 1) = 0 ) then get_char := False
else
begin
Value := Port[Base];
contr:=contr+Value;
get_char := True;
end;
end;
begin
z:=1;
while(z=1) do
begin
clrscr;
contr:=0;
writeln('Progam measure of fase');
writeln;
writeln('Input count measures');
Readln(i);
writeln;
writeln('Input time of measurements');
Readln(l);
Base:=MemW[$40:2]; {COM2}
OpenCom(Base,24,3 + 0 + 0); {4800,8-bit,1 stop-bit,no control error}
send_char(Base , 0); {start}
if(get_char(BASE)=TRUE) then k:=Value; {meassage about working of device}
k:=k and 1;
if(k=0) then
begin
send_char(Base , i); {number of measurements}
send_char(Base , l); {time of measurement}
for k:=1 to i do
begin
if(get_char(BASE)=TRUE) then k:=Value; {higer byte of freaquency}
freaquency:=k*256;
if(get_char(BASE)=TRUE) then k:=Value; {lower byte of freaquency}
freaquency:=freaquency+k;
freaquency_r:=10e5/freaquency; {convertion in Hz}
if(get_char(BASE)=TRUE) then k:=Value; {higer byte of fase}
fase:=k*256;
if(get_char(BASE)=TRUE) then k:=Value; {lower byte of fase}
fase:=fase+k;
if(freaquency<7) then {60MHz}
begin
divider:=1;
end;
if(freaquency>6)and(freaquency<$0E00) then {60/Nd+2}
begin
divider:=(75*freaquency)/512+1;
end;
if(freaquency>$0DFF)and(freaquency<$1C00) then {30/Nd+2}
begin
divider:=(75*freaquency)/1024+2;
end;
if(freaquency>$1BFF)and(freaquency<$3700) then {15/Nd+2}
begin
divider:=(75*freaquency)/2048+2;
end;
if(freaquency<$3700) then fase_r:=360*(freaquency_r*divider/6e7) {convertion}
else {fase measured MK}
begin
fase_r:=360*((2*fase)/freaquency);
end;
data[k][1]:=freaquency_r;
data[k][2]:=fase_r;
end;
if(get_char(BASE)=TRUE) then
begin
if(Value<>contr) then {control}
begin
z:=0;
writeln('Error COM port');
end
else
begin
l:=0;
while l=0 do
begin
clrscr;
writeln('Input number of measurements');
Readln(ms);
if(ms>100) then l:=1
else writeln('f=',data[ms,1],' fase=',data[ms,2]);
ReadKey;
end;
freaquency_r:=0;
fase_r:=0;
for k:=1 to i do {medium measurements}
begin
freaquency_r:=freaquency_r+data[k,1];
fase_r:=fase_r+data[k,2];
end;
freaquency_r:=freaquency_r/i;
fase_r:=fase_r/i;
Writeln('Medium f=',freaquency_r,' fase=',fase_r,' o');
end;
end;
end
else
begin
clrscr;
writeln('Error COM port');
z:=0;
end;
end;
end.
Выводы
В данной работе был спроектирован автоматический фазометр. Основной сложностью при его проектирование был выбор компонентой базы, так как данный фазометр должен измерять фазу у сигнала с частотой 100кГц с точностью 0.2%. Это эквивалентно измерению временных интервалов длительностью 20нс. Интегральных таймеров на такую частоту найдено не было. Из-за чего таймер был спроектирован на базе трех 4-разрядных счетчиков и генератора с программируемой частотой. Для измерения фазы сигнала вначале измеряется его частота с помощью микроконтроллера, а затем генератор программируется на частоту в 212 раз большую, чем частота сигнала. При активном уровне с выхода системы перехода напряжений через ноль, счетчик считает импульсы генератора, а затем микроконтроллер считывает их и передает компьютеру, где константы соответствующие частоте и фазе преобразуются в герцы и градусы и показываются оператору по его запросу.