Need help with COMM program 
Author Message
 Need help with COMM program

Hi all

At work, we use a "Paint thickness gauge" which can be hooked to a
PC serial port to download data using a communication software.

The documentation of the gauge indicates the speed, parity, word
length and stop bit to which the comm program should be set.

I have tried it with Telix, QuickLink, Procomm and Windows terminal,
they all worked fine with the gauge.

Now, I have to build a Pascal DOS program which will read the gauge,
process the data and print a report. I have been programming with
Turbo Pascal versions 6 and 7 for DOS for a few years and have no
problem with the processing and report parts of the program.

I don't know much about serial port tough. So could anyone provide
a short Pascal listing, or tell where to find one, that would show how
to initialize, configure and read a serial port ?

Thanks to anybody who can help

Pat.



Wed, 18 Jun 1902 08:00:00 GMT  
 Need help with COMM program

Quote:

>Hi all

>At work, we use a "Paint thickness gauge" which can be hooked to a
>PC serial port to download data using a communication software.

>The documentation of the gauge indicates the speed, parity, word
>length and stop bit to which the comm program should be set.

>I have tried it with Telix, QuickLink, Procomm and Windows terminal,
>they all worked fine with the gauge.

>Now, I have to build a Pascal DOS program which will read the gauge,
>process the data and print a report. I have been programming with
>Turbo Pascal versions 6 and 7 for DOS for a few years and have no
>problem with the processing and report parts of the program.

>I don't know much about serial port tough. So could anyone provide
>a short Pascal listing, or tell where to find one, that would show how
>to initialize, configure and read a serial port ?

>Thanks to anybody who can help

>Pat.

I have just the thing for you.  It's a unit I wrote some time ago to
appease all the posters requesting a program on how to access their
modems in TP.  It's fairly well documented and can be easily modified
for your needs.  I'm throwing in (at no additional charge) a "Dumb"
terminal Wrapper to demonstrate how to use the unit.  If you need
any additional help, contact me via email.  Have fun:

UNIT WCom;

{ -- Asychronous communications routines for Turbo Pascal  --
   Copyright (c) 1995 by Wayne Hoxsie. Revision date 5-27-95

   You may use this unit as you please as long as you mention
   me in your documentation.

Quote:
}

INTERFACE

PROCEDURE AsyncTransmit(ch1:char);
FUNCTION  AsyncRecieve:char;
PROCEDURE AsyncFlushComm;
FUNCTION  AsyncCharWaiting:BOOLEAN;
FUNCTION  AsyncCDetect:boolean;
PROCEDURE AsyncInit(port_num:byte);
PROCEDURE AsyncShutdown;

IMPLEMENTATION

USES DOS;

CONST
(****************************************************************************
  These are the common base addresses and IRQ's for the 4 COM ports.  These
  will need to be edited if you use non-standard addresses or IRQ's
*)

  port_base_id : array[0..4] of word = (0,$3f8,$2f8,$2e8,$3e8);
  port_IRQ : array[0..4] of byte = (0,4,3,4,3);

(****************************************************************************
  These are jusr the mneumonics for the UART registers which are accesses
  relative to the com port's base address.
*)
  IER=1;
  FCR=2;
  IIR=2;
  LCR=3;
  MCR=4;
  LSR=5;
  MSR=6;

VAR
(****************************************************************************
  The head and tail are mearly to keep track of how many characters are in
  the buffer.  If they are not equal, then there are characters waiting to
  be processed.  Since it is a circular buffer, there may be characters still
  in the buffer which have already been processed.
*)

  buf_head,buf_tail : word;
  com_buf : array[0..1024] of byte;

(****************************************************************************
  These are the variables which will hold the current com port info.
*)

  async_irq,port_base : word;

(****************************************************************************
  These are just the ASM CLI and RTI instructions used to prevent another
  interrupt during the processing of data directly related to the interrupt
  handler.
*)

PROCEDURE Disable; INLINE($FA);
PROCEDURE Enable;  INLINE($FB);

(****************************************************************************
  This is the actual interrupt handler.  When a character is recieved by the
  com port, it signals the 8259 PIC which flags the processor to run the
  following code.  It grabs the character from the UART register and puts it
  into our circular buffer to be processed by the program at a later time.
  This is the essence of "Interrupt Driven Communications."
*)

{$F+}                                 { Make it a FAR function }
PROCEDURE async_isr; INTERRUPT;
BEGIN
  com_buf[buf_head]:=port[port_base];
  inc(buf_head);
  IF buf_head = 1024 THEN
    buf_head := 0;
  port[$20]:=$20;
END;
{$F-}

(****************************************************************************
  This procedure mearly sends a character out the com port.
*)
PROCEDURE AsyncTransmit(ch1:CHAR);
VAR
  temp : BYTE;
BEGIN

(*
  First we poll the LSR until there are no characters waiting in the
  transmitter holding register.  The bit we check (bit 5) is the THRE
  (Transmit Holding Register Empty) bit.
*)

  repeat
    temp:=port[port_base + LSR] AND $20;
  until temp<>0;

(*
  Now we can place a character in the register for the UART to send out.
*)

  port[port_base]:=integer(ch1);
END;

(****************************************************************************
  This function just checks to see if a character is waiting to be processed.
  It doesn't effect the character at all.
*)
FUNCTION  AsyncCharWaiting:BOOLEAN;
BEGIN
  asynccharwaiting := buf_head<>buf_tail;
END;

(****************************************************************************
  This function pulls a character out of our buffer and increments the
  pointers appropriately so that the interrupt handler can put the next
  character at the right place.  If no character is available, then we
  return a 0.
*)

FUNCTION  AsyncRecieve:char;
VAR
  c1 : char;
BEGIN
(* First make sure a char is waiting *)
  if buf_head <> buf_tail then
  BEGIN
    disable;
    c1 := char(com_buf[buf_tail]);
    inc(buf_tail);
    if buf_tail = 1024 then
      buf_tail := 0;
    enable;
    asyncrecieve:=c1;
  END  else
    asyncrecieve:=#0;
END;

(****************************************************************************
  This flushes all characters out of the buffer and resets the pointers
*)

PROCEDURE AsyncFlushComm;
BEGIN
  disable;
  buf_head :=0;
  buf_tail :=0;
  enable;
END;

(****************************************************************************
  This procedure sets the DTR pin to the desired value--ON or OFF--to tell
  the program on the other end that we are ready or not-ready.
*)

PROCEDURE dtr(i : BOOLEAN);
VAR
  i1 : word;
BEGIN
  i1 := port[port_base + MCR] AND $00FE;
  if i then
  port[port_base + MCR]:= i1+1 else
  port[port_base + MCR] := i1;
END;

(****************************************************************************
  This tells us if a carrier is detected or not.
*)

FUNCTION  AsyncCDetect:boolean;
BEGIN
  asynccdetect := (port[port_base + MSR] AND $0080)<> 0;
END;

(****************************************************************************
  This is the procedure that must be called to set up our com port for
  operation.  This installs the interrupt and sets the registers to the
  desired values.
*)

PROCEDURE AsyncInit(port_num : byte);
VAR
  temp : word;
BEGIN
  port_base := port_base_id[port_num];
  async_irq := port_IRQ[port_num];
  setintvec(8 + async_irq, addr(async_isr));
  buf_head :=0;
  buf_tail := 0;
  port[port_base + LCR]:= $03;          { set N81 parameters }
  disable;
  temp := port[port_base + LSR];        { Read LSR to reset all bits }
  temp := port[port_base];              { clear any character still pending }
  temp := port[$21];                    { read the PIC mask }
  temp := temp AND((1 SHL async_irq)XOR $00FF);  {set appropriate bit }
  port[$21]:=temp;                      {set the PIC mask appropriately}
  port[port_base + IER]:=1;
  temp:=port[port_base + MCR];
  port[port_base + MCR]:= temp OR $0A;  {Set MCR }
  port[port_base + FCR]:=$c0;           {enable FIFO's on 16550A's }
  enable;
  dtr(TRUE);                            {tell the world, "We're ready!" }
END;

(****************************************************************************
  This resets all the stuff we set up in the first place.
*)
PROCEDURE AsyncShutdown;
VAR
  temp : integer;
  oldvec : pointer;
BEGIN
  if port_base<>0 then BEGIN
    disable;
    temp := port[$21];
    temp := temp OR ((1 SHL async_irq));  { unmask the PIC }
    port[$21]:= temp;
    port[port_base + IIR]:=0;             { shutdown the interrupts }
    port[port_base + MCR]:=3;
    getintvec(8,oldvec);
    setintvec(async_irq+8,oldvec);
    enable;
    port_base:=0;
  END;
END;

END.

(* END WCOM.PAS *)

program dumb_terminal;

uses dos,wcom,crt;

var
  temp : char;
  done : boolean;
  i,code : integer;

begin
  if(paramcount<1) then
    i:=1
  else
    val(paramstr(1),i,code);
  done:=false;
  asyncinit(2);
  repeat begin
    if keypressed then begin
      temp:=readkey;
      if temp=#27 then done:=true;
      asynctransmit(temp);
    end;
    if asynccharwaiting then
      write(asyncrecieve);
  end;
  until done;
  asyncshutdown;
end.

--

The Lab BBS, Alton IL, 618-462-0767
{*filter*} the ``Communications Decency Act!''
`finger' or ` http://www.*-*-*.com/ ~hoxsiew' for a PGP key.



Wed, 18 Jun 1902 08:00:00 GMT  
 Need help with COMM program

Quote:

> At work, we use a "Paint thickness gauge" which can be hooked to a
> PC serial port to download data using a communication software.

> The documentation of the gauge indicates the speed, parity, word
> length and stop bit to which the comm program should be set.

> I have tried it with Telix, QuickLink, Procomm and Windows terminal,
> they all worked fine with the gauge.

> Now, I have to build a Pascal DOS program which will read the gauge,
> process the data and print a report. I have been programming with
> Turbo Pascal versions 6 and 7 for DOS for a few years and have no
> problem with the processing and report parts of the program.

> I don't know much about serial port tough. So could anyone provide
> a short Pascal listing, or tell where to find one, that would show how
> to initialize, configure and read a serial port ?

Unless the bps rate is fairly low, you *can't* do this with a *short*
listing.

Setting the can be done in a "short" way by using something like this:

  Exec(GetEnv(COMSPEC),'/c mode com1 baud=96,8,n,1');

And you can just open COM1 as a file of byte.

The problem is that checking for errors, and preventing overruns takes
a fair amount of code, and much of it is best done in assembler (for
example, you want the receive character routine to be interrupt driven).

I'd recommend buying Asyunch Pro from TurboPower Software. It's almost
overkil for what you are doing, but better to have more tools than you
need now, in case you need to do something fancier later.

Leonard Erickson (aka Shadow)




Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Help Request: Comm Program Routines

2. Please help with COMM program

3. PLEASE HELP - need serial comm

4. HELP NEEDED: With my COMM prog and system info

5. Need help using Comm port

6. Need HELP FINISHING PROGRAM (posted program) PASCAL

7. Help needed (running a program from a program).

8. Help needed (running a program from a program).

9. Emergency Help Needed: C2pascal program needed

10. Need help with Hailstone Sequence program please Help

11. Help, need help for schedule program

12. HELP: I need help with a programming comp

 

 
Powered by phpBB® Forum Software