Составить программу для тестирования последовательного интерфейса - 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.

Оцени полезность:

12   голосов , оценка 3.75 из 5
Похожие ответы