Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 922
  • Last Modified:

Send & Receive ASCII via Serial Port ( 16-bit Borland C )

I am interested to develop a communication program between PC & external device via serial port. I just follow an example from www.beyondlogic.org and  capable of establishing communication on 38400,N,8,1 protocol. Compiler use is Borland C ( 16-bit DOS environment ). I would like to learn on how to send & received ASCII text via this program. The ASCII texts that need to be sent are predefined ( a part of the program ).

Here's the code i got from http://www.beyondlogic.org 

#include <dos.h>
#include <stdio.h>
#include <conio.h>

#define PORT1 0x3F8  /* Port Address Goes Here */
#define INTVECT 0x0C /* Com Port's IRQ here (Must also change PIC setting) */

  /* Defines Serial Ports Base Address */
  /* COM1 0x3F8                        */
  /* COM2 0x2F8                         */
  /* COM3 0x3E8                         */
  /* COM4 0x2E8                         */

int bufferin = 0;
int bufferout = 0;
char ch;
char buffer[1025];

void interrupt (*oldport1isr)();

void interrupt PORT1INT()  /* Interrupt Service Routine (ISR) for PORT1 */
{
 int c;
 do { c = inportb(PORT1 + 5);
      if (c & 1) {buffer[bufferin] = inportb(PORT1);
              bufferin++;
              if (bufferin == 1024) {bufferin = 0;}}
    }while (c & 1);
 outportb(0x20,0x20);
}

void main(void)
{
 int c;
 outportb(PORT1 + 1 , 0);        /* Turn off interrupts - Port1 */

 oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector of later
                            recovery */

 setvect(INTVECT, PORT1INT);     /* Set Interrupt Vector Entry */
                         /* COM1 - 0x0C */
                         /* COM2 - 0x0B */
                         /* COM3 - 0x0C */
                         /* COM4 - 0x0B */

 /*         PORT 1 - Communication Settings         */

 outportb(PORT1 + 3 , 0x80);  /* SET DLAB ON */
 outportb(PORT1 + 0 , 0x0C);  /* Set Baud rate - Divisor Latch Low Byte */
                        /* Default 0x03 =  38,400 BPS */
                        /*         0x01 = 115,200 BPS */
                        /*         0x02 =  57,600 BPS */
                        /*         0x06 =  19,200 BPS */
                        /*         0x0C =   9,600 BPS */
                        /*         0x18 =   4,800 BPS */
                        /*         0x30 =   2,400 BPS */
 outportb(PORT1 + 1 , 0x00);  /* Set Baud rate - Divisor Latch High Byte */
 outportb(PORT1 + 3 , 0x03);  /* 8 Bits, No Parity, 1 Stop Bit */
 outportb(PORT1 + 2 , 0xC7);  /* FIFO Control Register */
 outportb(PORT1 + 4 , 0x0B);  /* Turn on DTR, RTS, and OUT2 */

 outportb(0x21,(inportb(0x21) & 0xEF));  /* Set Programmable Interrupt Controller */
                               /* COM1 (IRQ4) - 0xEF  */
                               /* COM2 (IRQ3) - 0xF7  */
                               /* COM3 (IRQ4) - 0xEF  */
                               /* COM4 (IRQ3) - 0xF7  */

 outportb(PORT1 + 1 , 0x01);  /* Interrupt when data received */

 printf("\nSample Comm's Program. Press ESC to quit \n");

 do {

     if (bufferin != bufferout){ch = buffer[bufferout];
                        bufferout++;
                        if (bufferout == 1024) {bufferout = 0;}
                        printf("%c",ch);}

     if (kbhit()){c = getch();
              outportb(PORT1, c);}

    } while (c !=27);

 outportb(PORT1 + 1 , 0);       /* Turn off interrupts - Port1 */
 outportb(0x21,(inportb(0x21) | 0x10));  /* MASK IRQ using PIC */
                               /* COM1 (IRQ4) - 0x10  */
                               /* COM2 (IRQ3) - 0x08  */
                               /* COM3 (IRQ4) - 0x10  */
                               /* COM4 (IRQ3) - 0x08  */
 setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */

}

I have no idea where I can put the ASCII text that need to be sent in this program.


0
eazrul
Asked:
eazrul
1 Solution
 
grg99Commented:
This code is kinda shaky, especially the output part:

   outportb(PORT1, c);

This puts the character in variable c to the port.  This will kinda work "okay" if you'r reading from the keyboard, because the keyboard is usually getting pressed much slower than the serial port can send characters.  But if you put this line in a loop, sending a string,

" for( i = 0; i < strlen(str); i++ ) outportb( PORT1, str[i] );"

it's going to overflow the serial port buffer.  You might get away with sending SHORT strings (16 to 64 at a time), as some serial ports have 16 to 64 byte buffers (if they have the 16550 thru 16750 chips).  But you certainly will get into trouble if you try to send more than that at a gulp.

The code should check the tx empty bit in PORT1+5 before sending the next character, something like:

while( inportb( PORT1 + 5 ) & TXREADYBIT == 0 ) /* wait for it */;
0
 
ankuratvbCommented:
Check this link:

http://www.beyondlogic.org/terminal/terminal.htm

It has sample code for a lite version of HyperTerminal,for DOS.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now