Смекни!
smekni.com

Система ПЭВМ IBM PCAT автоматический фазометр (стр. 4 из 4)

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 раз большую, чем частота сигнала. При активном уровне с выхода системы перехода напряжений через ноль, счетчик считает импульсы генератора, а затем микроконтроллер считывает их и передает компьютеру, где константы соответствующие частоте и фазе преобразуются в герцы и градусы и показываются оператору по его запросу.