Составить программу для тестирования последовательного интерфейса - Assembler
Формулировка задачи:
Составить программу для тестирования последовательного интерфейса RS232C. Номер интерфейса COM1 или COM2 ввести с дисплея. Тест должен включать инициализацию порта COM1 или COM2 и процедуры посылки в порт последовательности печатных символов. Программа должна принимать посланную последовательность и сравнивать ее с посылаемой. При несовпадении или неисправности интерфейса выдать сообщение об ошибке.
Решение задачи: «Составить программу для тестирования последовательного интерфейса»
textual
Листинг программы
{ Этот модуль содержит процедуры и функции для работы с COM портом } {$IFNDEF Debug} {$D-,S-,L-} {$ENDIF} {$B-,R-,V-,X+,N+,E-,A-,T-,F-,Q-,P-} {.$G+} UNIT C2_Proc; INTERFACE USES _Timer,C2_Const; CONST { Константы для обозначения порта в процедуре InitAUX } { численно равны смещению в области данных BIOS $0040:Ofs } COM1 = 0; COM2 = 2; COM3 = 4; COM4 = 6; PROCEDURE InitAUX (COM : Byte; Frec :Word; LenSym,LenStop,Parity :Byte); { Эта процедура в отличие от InitAUX использует внутреннюю переменную } { BaseAdr } PROCEDURE InitCOM (Frec :Word; LenSym,LenStop,Parity :Byte); PROCEDURE InitCOMmode (Frec :Word; Mode :Byte); PROCEDURE SetDTR; { DTR = +12 V } PROCEDURE SetRTS; { RTS = +12 V } PROCEDURE SetDTR_RTS; PROCEDURE SetDTR_RTS_OUT2; PROCEDURE SetOUT1; PROCEDURE SetOUT2; PROCEDURE ClrDTR; { DTR = -12 V } PROCEDURE ClrRTS; { RTS = -12 V } PROCEDURE ClrDTR_RTS; PROCEDURE ClrDTR_RTS_OUT2; PROCEDURE ClrOUT1; PROCEDURE ClrOUT2; FUNCTION WaitCTS : BOOLEAN; FUNCTION WaitDSR : BOOLEAN; FUNCTION WaitRxDReady : BOOLEAN; FUNCTION WaitTxDReady : BOOLEAN; FUNCTION ReadLCR : Byte; FUNCTION ReadLSR : Byte; FUNCTION ReadMCR : Byte; FUNCTION ReadMSR : Byte; FUNCTION ReadIER : Byte; FUNCTION GetCTS : Byte;{ = 0 при CTS=0(-12V), <>0 при CTS=1(+12V)} FUNCTION GetDSR : Byte;{ = 0 при DSR=0(-12V), <>0 при DSR=1(+12V)} FUNCTION GetRI : Byte;{ = 0 при RI =0(-12V), <>0 при RI =1(+12V)} FUNCTION GetDCD : Byte;{ = 0 при DCD=0(-12V), <>0 при DCD=1(+12V)} PROCEDURE SetC2NoInt; {запретить прерывания } PROCEDURE SetIntTxD; {разрешить прерывания по готовности передатчика } PROCEDURE SetIntRxD; {разрешить прерывания по готовности приёмника } PROCEDURE SetIntErr; {разрешить прерывания по возникновении ошибки } PROCEDURE SetIntModem;{разрешить прерывания при изменении сигнала модема} PROCEDURE SetIntCOM(Ints:Byte);{разрешить прерывания } FUNCTION Num_COM : Byte; {возвращает число адаптеров последоват. связи} PROCEDURE ClearCOM; {очистка буфера приёма м/с } FUNCTION TypeUART : Byte;{возвращает тип м/c текущего порта } FUNCTION SetFIFO (Level:Byte):BOOLEAN;{устанавливает глубину FIFO } FUNCTION GetCOMBase(NPort:Word):Word; FUNCTION SetCOMBase(NPort:Word):Word; FUNCTION BaseAddr2NumCOM : Byte; PROCEDURE DisableCOM1; {запретить прерывание от COM1 на ПКП} inline( $E4 / $21 / { in al,21h } $0C / $10 / { or al,00010000b } $E6 / $21 ); { out 21h,al } PROCEDURE EnableCOM1; {разрешить прерывание от COM1 на ПКП} inline( $E4 / $21 / { in al,21h } $24 / $EF / { and al,11101111b } $E6 / $21 ); { out 21h,al } PROCEDURE DisableCOM2; {запретить прерывание от COM2 на ПКП} inline( $E4 / $21 / { in al,21h } $0C / $08 / { or al,00001000b } $E6 / $21 ); { out 21h,al } PROCEDURE EnableCOM2; {разрешить прерывание от COM2 на ПКП} inline( $E4 / $21 / { in al,21h } $24 / $F7 / { and al,11110111b } $E6 / $21 ); { out 21h,al } PROCEDURE DisableCOM3; {запретить прерывание от COM3 на ПКП} inline( $E4 / $21 / { in al,21h } $0C / $10 / { or al,00010000b } $E6 / $21 ); { out 21h,al } PROCEDURE EnableCOM3; {разрешить прерывание от COM3 на ПКП} inline( $E4 / $21 / { in al,21h } $24 / $EF / { and al,11101111b } $E6 / $21 ); { out 21h,al } PROCEDURE DisableCOM4; {запретить прерывание от COM4 на ПКП} inline( $E4 / $21 / { in al,21h } $0C / $08 / { or al,00001000b } $E6 / $21 ); { out 21h,al } PROCEDURE EnableCOM4; {разрешить прерывание от COM4 на ПКП} inline( $E4 / $21 / { in al,21h } $24 / $F7 / { and al,11110111b } $E6 / $21 ); { out 21h,al } VAR BaseAdr : Word; IMPLEMENTATION PROCEDURE InitAUX(COM : Byte; Frec :Word; LenSym,LenStop, Parity : Byte); assembler; asm push es { в переменной COM - смещение ( $0040:COM ) } push dx push bx push ax mov ax,40h mov es,ax xor bh,bh mov bl,COM mov dx,es:[bx] {dx:=base} add dx,3 {устанавливаем делитель} mov al,80h out dx,al {base+3} dec dx dec dx mov bx,Frec mov al,bh out dx,al {base+1} dec dx mov al,bl out dx,al {base} xor al,al or al,LenSym or al,LenStop or al,Parity add dx,3 out dx,al {base+3} {управление линией (формат обмена)} dec dx dec dx mov al,ierNoInt out dx,al {base+1} {разрешение/запрет прерывания } pop ax pop bx pop dx pop es END; PROCEDURE InitCOM (Frec :Word; LenSym,LenStop,Parity :Byte); assembler; asm push es push dx push bx push ax mov dx,BaseAdr {dx:=base} add dx,3 {устанавливаем делитель } mov al,80h out dx,al {base+3} dec dx dec dx mov bx,Frec mov al,bh out dx,al {base+1} dec dx mov al,bl out dx,al {base} xor al,al or al,LenSym or al,LenStop or al,Parity add dx,3 out dx,al {base+3} {управление линией (формат обмена)} dec dx dec dx mov al,ierNoInt out dx,al {base+1} {разрешение/запрет прерывания } pop ax pop bx pop dx pop es END; PROCEDURE InitCOMmode(Frec :Word; Mode :Byte); assembler; asm push es push dx push bx push ax mov dx,BaseAdr {dx:=base} add dx,3 {устанавливаем делитель } mov al,80h out dx,al {base+3} dec dx dec dx mov bx,Frec mov al,bh out dx,al {base+1} dec dx mov al,bl out dx,al {base } mov al,Mode add dx,3 out dx,al {base+3} {управление линией (формат обмена)} dec dx dec dx mov al,ierNoInt out dx,al {base+1} {разрешение/запрет прерывания } pop ax pop bx pop dx pop es END; PROCEDURE SetDTR; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx or al,mcrSetDTR out dx,al pop ax pop dx END; PROCEDURE ClrDTR; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx and al,NOT mcrSetDTR out dx,al pop ax pop dx END; PROCEDURE SetRTS; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx or al,mcrSetRTS out dx,al pop ax pop dx END; PROCEDURE ClrRTS; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx and al,NOT mcrSetRTS out dx,al pop ax pop dx END; PROCEDURE SetOUT1; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx or al,mcrSetOUT1 out dx,al pop ax pop dx END; PROCEDURE ClrOUT1; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx and al,NOT mcrSetOUT1 out dx,al pop ax pop dx END; PROCEDURE SetOUT2; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx or al,mcrSetOUT2 out dx,al pop ax pop dx END; PROCEDURE ClrOUT2; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx and al,NOT mcrSetOUT2 out dx,al pop ax pop dx END; PROCEDURE SetDTR_RTS; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx or al,mcrSetRTS+mcrSetDTR out dx,al pop ax pop dx END; PROCEDURE ClrDTR_RTS; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR mov al,0 out dx,al pop ax pop dx END; PROCEDURE SetDTR_RTS_OUT2; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx or al,mcrSetRTS+mcrSetDTR+mcrSetOUT2 out dx,al pop ax pop dx END; PROCEDURE ClrDTR_RTS_OUT2; assembler; asm push dx push ax mov dx,BaseAdr add dx,MCR in al,dx and al,NOT (mcrSetRTS+mcrSetDTR+mcrSetOUT2) out dx,al pop ax pop dx END; FUNCTION WaitCTS : BOOLEAN; assembler; asm push dx push cx mov cx,Time1sec mov TimerDec,cx mov dx,BaseAdr add dx,MSR @1: mov cx,TimerDec jcxz @TimeOut in al,dx test al,msrCTS jz @1 mov al,1 jmp @Exit @TimeOut: xor ax,ax @Exit: pop cx pop dx END; FUNCTION WaitDSR : BOOLEAN; assembler; asm push dx push cx mov cx,Time1sec mov TimerDec,cx mov dx,BaseAdr add dx,MSR @1: mov cx,TimerDec jcxz @TimeOut in al,dx test al,msrDSR jz @1 mov al,1 jmp @Exit @TimeOut: xor ax,ax @Exit: pop cx pop dx END; FUNCTION WaitTxDReady : BOOLEAN; assembler; asm push dx push cx mov cx,Time1sec mov TimerDec,cx mov dx,BaseAdr add dx,LSR @1: mov cx,TimerDec jcxz @TimeOut in al,dx test al,lsrReadyOut jz @1 mov al,1 jmp @Exit @TimeOut: xor ax,ax @Exit: pop cx pop dx END; FUNCTION WaitRxDReady : BOOLEAN; assembler; asm push dx push cx mov cx,Time1sec mov TimerDec,cx mov dx,BaseAdr add dx,LSR @1: mov cx,TimerDec jcxz @TimeOut in al,dx test al,lsrReadyIn jz @1 mov al,1 jmp @Exit @TimeOut: xor ax,ax @Exit: pop cx pop dx END; FUNCTION ReadLSR : Byte; assembler; asm push dx mov dx,BaseAdr add dx,LSR in al,dx pop dx END; FUNCTION ReadLCR : Byte; assembler; asm push dx mov dx,BaseAdr add dx,LCR in al,dx pop dx END; FUNCTION ReadMSR : Byte; assembler; asm push dx mov dx,BaseAdr add dx,MSR in al,dx pop dx END; FUNCTION ReadMCR : Byte; assembler; asm push dx mov dx,BaseAdr add dx,MCR in al,dx pop dx END; FUNCTION ReadIER : Byte; assembler; asm push dx mov dx,BaseAdr add dx,IER in al,dx pop dx END; PROCEDURE SetC2NoInt; assembler; asm push dx push ax mov dx,BaseAdr add dx,IER xor al,al out dx,al pop ax pop dx END; PROCEDURE SetIntTxD; assembler; asm push dx push ax mov dx,BaseAdr add dx,IER in al,dx or al,ierTxD out dx,al pop ax pop dx END; PROCEDURE SetIntRxD; assembler; asm push dx push ax mov dx,BaseAdr add dx,IER in al,dx or al,ierRxD out dx,al pop ax pop dx END; PROCEDURE SetIntErr; assembler; asm push dx push ax mov dx,BaseAdr add dx,IER in al,dx or al,ierError out dx,al pop ax pop dx END; PROCEDURE SetIntModem; assembler; asm push dx push ax mov dx,BaseAdr add dx,IER in al,dx or al,ierModem out dx,al pop ax pop dx END; PROCEDURE SetIntCOM(Ints:Byte);{разрешить прерывания } assembler; asm push dx push ax mov dx,BaseAdr add dx,IER in al,dx or al,Ints out dx,al pop ax pop dx END; FUNCTION GetCTS : Byte; assembler; asm push dx mov dx,BaseAdr add dx,MSR in al,dx and al,msrCTS pop dx END; FUNCTION GetDSR : Byte; assembler; asm push dx mov dx,BaseAdr add dx,MSR in al,dx and al,msrDSR pop dx END; FUNCTION GetRI : Byte; assembler; asm push dx mov dx,BaseAdr add dx,MSR in al,dx and al,msrRI pop dx END; FUNCTION GetDCD : Byte; assembler; asm push dx mov dx,BaseAdr add dx,MSR in al,dx and al,msrDCD pop dx END; FUNCTION Num_COM : Byte; {возвращает число адаптеров последоват. связи} assembler; asm mov ax,40h mov es,ax mov ax,es:[10h] and ax,0E00h {$IFOPT G+} shr ax,9 {$ELSE} mov al,ah shr al,1 xor ah,ah {$ENDIF} END; PROCEDURE ClearCOM; assembler; asm {$IFOPT G+} pusha {$ELSE} {$ENDIF} @@Start: mov dx,BaseAdr in al,dx add dx,LSR in al,dx and al,lsrReadyIn jnz @@Start {$IFOPT G+} popa {$ELSE} {$ENDIF} END; FUNCTION TypeUART : Byte;{возвращает тип м/c текущего порта } assembler; asm END; FUNCTION SetFIFO (Level:Byte):BOOLEAN;{устанавливает глубину FIFO } assembler; asm mov al, Level mov dx, BaseAdr add dx, FCR or al, 1 out dx, al in al, dx and al, 0C0h xor al, 0C0h jz @@Is16550 mov ax, 0 jmp @@Exit @@Is16550: mov ax, 1 @@Exit: END; FUNCTION GetCOMBase(NPort:Word):Word; BEGIN case NPort of 1 : GetCOMBase:=COM1base; 2 : GetCOMBase:=COM2base; 3 : GetCOMBase:=COM3base; 4 : GetCOMBase:=COM4base; else GetCOMBase:=0; end; END; FUNCTION SetCOMBase(NPort:Word):Word; BEGIN case NPort of 1 : BaseAdr:=COM1base; 2 : BaseAdr:=COM2base; 3 : BaseAdr:=COM3base; 4 : BaseAdr:=COM4base; else BaseAdr:=0; end; SetCOMBase:=BaseAdr; END; FUNCTION BaseAddr2NumCOM : Byte; VAR COM_Array : array [1..4] of Word absolute $0040:$0000; VAR i : Byte; BEGIN i:=Num_COM; repeat if BaseAdr=COM_Array[i] then break; Dec(i); until i=0; BaseAddr2NumCOM:=i; END; END.