Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CTS/RTS Handshaking

Status
Not open for further replies.

deanlwvu

Technical User
Jul 23, 2003
25
0
0
US
Hello all,

I need to know how to set up handshaking using CTS and RTS on an RS232 serial port. Using Turbo C. I can transfer data to the port, but if I transfer it too fast then it skips characters. Handshaking will solve this, but I'm not sure how to incorporate it into my program.

Thanks.
 
Can you paste the code which you use to send characters to the serial port?
 
Here you go.....

for(count = 0; count <= 3360; count++){
if(fscanf(outfile, &quot; %s&quot;, sequence)!=EOF){
fscanf(outfile, &quot;%s&quot;, sequence);
for(count2 = 0; count2 <= 3360; count2++){
outportb(PORT1, sequence[count2]);
}
}
}
 
And I have to use handshaking. That's the whole point of the program, to verify that a system has proper handshaking wiring.

Code:
    for(count = 0; count <= 3360; count++){
	if(fscanf(outfile, &quot; %s&quot;, sequence)!=EOF){
		fscanf(outfile, &quot;%s&quot;, sequence);
		for(count2 = 0; count2 <= 3360; count2++){
			outportb(PORT1, sequence[count2]);
			}
		}
	}
 
First things first - what are those loops doing?

You're calling fscanf() twice per loop, which means half your file is being thrown away before you do anything.

Unless your file contains strings of exactly 3361 characters, you're going to send a lot of junk characters to the serial port.

Calling an input file 'outfile' doesn't seem right.

If you're wanting to dump a file to the serial port, then something like this would be better
Code:
char buff[1000];
while ( fgets( buff, 1000, infile ) != NULL ) {
  for ( i = 0 ; i < strlen(buff) ; i++ ) {
    outportb(PORT1, buff[i]);
  }
}

Now you need to get this
Download parts A to D

Now the key information is as follows

Serial ports are controlled by a number of registers which are offset from the PORT1 register you have used.
Code:
03F8  -W  serial port, transmitter holding register (THR), which contains the
	  character to be sent. Bit 0 is sent first.
		bit 7-0	  data bits when DLAB=0 (Divisor Latch Access Bit)
03F8  R-  receiver buffer register (RBR), which contains the received
	  character. Bit 0 is received first
		 bit 7-0   data bits when DLAB=0 (Divisor Latch Access Bit)
03F8  RW  divisor latch low byte (DLL) when DLAB=1 (see #P0876)
03F9  RW  divisor latch high byte (DLM) when DLAB=1 (see #P0876)
03F9  RW  interrupt enable register (IER) when DLAB=0 (see #P0877)
03FA  R-  interrupt identification register (see #P0878)
	Information about a pending interrupt is stored here. When the ID
	  register is addressed, thehighest priority interrupt is held, and
	  no other interrupts are acknowledged until the CPU services that
	  interrupt.
03FA  -W  16650 FIFO Control Register (FCR) (see #P0879)
03FB  RW  line control register (LCR) (see #P0880)
03FC  RW  modem control register (see #P0881)
03FD  R-  line status register (LSR) (see #P0882)
03FE  R-  modem status register (MSR) (see #P0883)
03FF  RW  scratch register (SCR)
	(not used for serial I/O; available to any application using 16450,
	  16550) (not present on original 8250)
So for example, if PORT1 is 03F8, then what you're doing when you do
Code:
outportb(PORT1, buff[i])
is writing to the &quot;transmitter holding register&quot;.

OK, so now for handshaking
Code:
Bitfields for serial port Line Status Register (LSR):
Bit(s)	Description	(Table P0882)
 7      =0  reserved
        =1  on some chips produced by UMC
 6	transmitter shift and holding registers empty
 5	transmitter holding register empty (THRE)
	Controller is ready to accept a new character to send.
Recall that the LSR register would be at address 03FD (or PORT1+5)
The interesting bit here is bit 5, since it tells us whether the transmit holding register is empty or not.
If it is empty, we're good to go to send another character.

So the modified loop might look something like this
Code:
char buff[1000];
while ( fgets( buff, 1000, infile ) != NULL ) {
  for ( i = 0 ; i < strlen(buff) ; i++ ) {
    /* send a character */
    outportb(PORT1, buff[i]);

    /* wait for it to finish sending */
    while ( (inportb(PORT1+5) & 0x20) == 0 ) {
      /* loop here until the current char has been sent */
      /* the bit being tested will be set and this loop will exit */
    }
  }
}

The actual &quot;Clear to Send&quot; flag is in the Modem Status Register (MSR), but I'll leave you to get those Ralph Brown files and read up for yourself (the information you want is in the PORTS.B file).
 
Alright, that's all fine and good. You know your stuff, and when you give advice, it would be a little more helpful if you weren't as demeaning.

We're not expert programmers, that's why we post on here.

Also, I called the file outfile, because the serial port is sending the file out to a &quot;dumb terminal&quot; and the terminal then processes the text. My array size is the size of the text file, and that's why I used that size.

I'm not an expert programmer (obviously) and that's why I asked for help.

Thanks for the advice.
 
After doing some manipulation, I found out that you were examining the wrong register. You needed to be examining the MSR (modem status register) instead of the Line Status register.

I guess that nobody is perfect.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top