⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 485test.cpp

📁 DOS下RS485通信编程部分程序
💻 CPP
字号:
#include <dos.h>
#include <bios.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MDMDAT1 0x03F8
#define MDMSTS1 0x03FD
#define MDMCOM1 0x03FB
#define MDMDAT2 0x02F8
#define MDMSTS2 0x02FD            /* Address of modem port 2 status */
#define MDMCOM2 0x02FB            /* Address of modem port 2 command */
#define MDMDAT3 0x03E8            /* Address of modem port 3 data */
#define MDMSTS3 0x03ED            /* Address of modem port 3 status  */
#define MDMCOM3 0x03EB            /* Address of modem port 3 command */
#define MDMDAT4 0x02E8            /* Address of modem port 4 data */
#define MDMSTS4 0x02ED            /* Address of modem port 4 status */
#define MDMCOM4 0x02EB            /* Address of modem port 4 command */
#define MDMINTV 0x000C            /* Com 1 & 3 interrupt vector */
#define MDINTV2 0x000B            /* Com 2 & 4 interrupt vector */
#define MDMINTO 0x0EF             /* Mask to enable IRQ3 for port 1 & 3 */
#define MDINTO2 0x0F7             /* Mask to enable IRQ4 for port 2 & 4 */
#define MDMINTC 0x010             /* Mask to Disable IRQ4 for port 1 & 3 */
#define MDINTC2 0x008             /* Mask to Disable IRQ3 for port 2 & 4 */
#define INTCONT 0x0021            /* 8259 interrupt controller ICW2-3 */
#define INTCON1 0x0020            /* Address of 8259 ICW1 */
#define CBS     2048              /* Communications port buffer size */
#define XOFF    0x13              /* XON/XOFF */
#define XON     0x11
#define CARRIER_ON  0x80          /* Return value for carrier detect */

#ifndef TIMEOUT         /* Define Timeout if not already */
#define TIMEOUT -1
#endif
#define USR_BRK -2
/* prototypes for externally called functions */
int  comm_open  ( int portid,long speed );
void comm_close ( void );
void comm_flush ( void );
int  comm_avail ( void );
void comm_putc  ( unsigned char c );
int  comm_getc  ( unsigned seconds );
void flsh_dtr   ( void );
int  carrier    ( void );
////////////////////////

static int   MODEM_STAT;          /* 8250 modem status register */
static int   dat8250;             /* 8250 data register */
static int   stat8250;            /* 8250 line-status register */
static int   com8250;             /* 8250 line-control register */
static char  en8259;              /* 8259 IRQ enable mask */
static char  dis8259;             /* 8259 IRQ disable mask */
static unsigned int intv;         /* interrupt number to usurp */
static char  buffer[CBS];         /* Communications circular buffer */
static char *inptr;               /* input address of circular buffer */
static char *outptr;              /* output address of circular buffer */
static int   c_in_buf = 0;        /* count of characters received */
static int   xoffpt;              /* amount of buffer that forces XOFF */
static int   xonpt;               /* amount of buffer that unXOFFs */

static void interrupt ( far *oldvec ) (...);
int xonxoff = 0;                          /* auto xon/xoff support flag */
int xofsnt  = 0;                          /* XOFF transmitted flag */
int xofrcv  = 0;                          /* XOFF received flag */

void interrupt serint (... )
{
   *inptr++ = inportb ( dat8250 );        /* Store character in buffer */
   c_in_buf++;                            /* and increment count */
   if ( xonxoff )
   {                       /* if xon/xoff auto-support is on */
      if ( c_in_buf > xoffpt && ! xofsnt )
       {  /* then if buf nearly full */
         comm_putc ( XOFF );              /* send an XOFF h*/
         xofsnt = 1;                      /* and say so */
       }
   }
   disable ( );                           /* ints off for ptr change */
   if ( inptr == &buffer[CBS] )           /* Set buffer input pointer */
      inptr = buffer;
   enable ( );
   outportb ( 0x20, 0x20 );               /* Generic EOI to 8259 */
}


void comm_close ( void )
{             /* restore previous settings of 8259 */
    outportb ( com8250 + 1, 0x08 );      /* Drop OUT2 */
    outportb ( com8250 + 1, 0x00 );      /* Drop DTR and RTS */
    outportb ( INTCONT, dis8259 | inportb ( INTCONT ) );
       /* Disable com interrupt at 8259 */
     setvect ( intv, oldvec );      /* Reset original interrupt vector */
}

void dobaud ( unsigned baudrate )       /* parses baud integer to mask,
                                         * re-inits port accordingly */
{
   unsigned char portval;
   unsigned char blo, bhi;
   switch  ( baudrate ) {          /* Baud rate LSB's and MSB's */
       case 50:     bhi = 0x9;  blo = 0x00;  break;
       case 75:     bhi = 0x6;  blo = 0x00;  break;
       case 110:    bhi = 0x4;  blo = 0x17;  break;
       case 150:    bhi = 0x3;  blo = 0x00;  break;
       case 300:    bhi = 0x1;  blo = 0x80;  break;
       case 600:    bhi = 0x0;  blo = 0xC0;  break;
       case 1200:   bhi = 0x0;  blo = 0x60;  break;
       case 1800:   bhi = 0x0;  blo = 0x40;  break;
       case 2000:   bhi = 0x0;  blo = 0x3A;  break;
       case 2400:   bhi = 0x0;  blo = 0x30;  break;
       case 4800:   bhi = 0x0;  blo = 0x18;  break;
       case 9600:   bhi = 0x0;  blo = 0x0C;  break;
       case 12800:  bhi = 0x0;  blo = 0x09;  break;
       case 19200:  bhi = 0x0;  blo = 0x03;  break;
       case 57600:  bhi = 0x0;  blo = 0x02;  break;
       case 115200: bhi = 0x0;  blo = 0x01;  break;
       default:
           return;
   }
   portval = inportb ( com8250 );         /* read Line-Control Reg val */
   outportb ( com8250, portval | 0x80 );  /* set high bit for baud init */
   outportb ( dat8250, blo );             /* Send LSB for baud rate */
   outportb ( dat8250 + 1, bhi );         /* Send MSB for baud rate */
   outportb ( com8250, portval );         /* Reset initial value at LCR */
}

/* installs comm interrupts */
int comm_open ( int portid, long speed )
{
   unsigned int be = biosequip ( );      /* to get # installed serial ports */
   be <<= 4;                    /* shift-wrap high bits off */
   be >>= 13;                   /* shift down to low bits */
   if ( be >= portid || portid >= 3)
     {
      if ( portid == 1 )
       {
          dat8250  = MDMDAT1;
          stat8250 = MDMSTS1;
          com8250  = MDMCOM1;
          dis8259  = MDMINTC;
          en8259   = MDMINTO;
          intv = MDMINTV;
       }
      else if ( portid == 2 )
       {
          dat8250  = MDMDAT2;
          stat8250 = MDMSTS2;
          com8250  = MDMCOM2;
          dis8259  = MDINTC2;
          en8259   = MDINTO2;
          intv = MDINTV2;
       }
      else if ( portid == 3 )
       {                /* Ports 3 & 4 cannot be checked */
          dat8250  = MDMDAT3;           /* with biosquip( ) */
          stat8250 = MDMSTS3;
          com8250  = MDMCOM3;
          dis8259  = MDMINTC;
          en8259   = MDMINTO;
          intv = MDMINTV;
       }
      else if ( portid == 4 )
       {
          dat8250  = MDMDAT4;
          stat8250 = MDMSTS4;
          com8250  = MDMCOM4;
          dis8259  = MDINTC2;
          en8259   = MDINTO2;
          intv = MDINTV2;
       }
     else  return ( 0 );

      MODEM_STAT = dat8250 + 6;           /* Define Modem Status Register */

      dobaud ( speed );                   /* set baud */
      inptr = outptr = buffer;            /* set circular buffer values */
      c_in_buf = 0;
      oldvec = getvect ( intv );          /* Save old int vector */
      setvect  ( intv, serint );          /* Set up SERINT as com ISR */
      outportb ( com8250,     0xb );      /* 8 bits no parity  to 0x?fb*/


//////////////////////////////////
       outportb(com8250+1,0x09);       // RTS 0 ->ADM485 1,disable Out;
//      outportb ( com8250 + 1, 0xb );  /* Assert OUT2, RTS, and DTR to 0x?fc*/
//////////
      inportb  ( dat8250 );           /* to 0x?f8 */
      outportb ( dat8250 + 1, 0x1 );  /* Receiver-Data-Ready int to 0x?f9*/
      outportb ( INTCONT, en8259 & inportb ( INTCONT ) );
                                          /* Enable 8259 interrupts */
      xoffpt = CBS - 128;                 /* chars in buff to send XOFF */
      xonpt  = CBS - xoffpt;              /* chars in buff to send XON */
     }
   else   be = 0;
   return ( be );
}


int comm_avail ( )       /* returns # characters available in buffer */
{
    return ( c_in_buf );
}


void comm_putc ( unsigned char c )      /* sends char out port */
{
  while ( ( inportb ( stat8250 ) & 0x20 ) == 0 );
  outportb ( dat8250, c );            /* then send it */
}

int comm_getc ( unsigned seconds )         /* gets char from buffer */
{
    int c;
    long get_tm, end_tm;

    register char * ptr;
    if ( c_in_buf < xonpt && xofsnt ) {   /* Check if we need to send */
       xofsnt = 0;                        /* an XON to the host after */
       comm_putc ( XON );                 /* we had to send an XOFF */
       }

    get_tm = biostime(0,0);               /* If character not ready */
    end_tm = get_tm + (18 * seconds);     /* then wait til one is   */
                                          /* or return TIMEOUT */
    do {
        if(kbhit()) {                     /* If key pressed, Timeout */
            getch();                      /* is returned */
            comm_putc('\20');             /* send 'space' to modem to */
        return(USR_BRK);                  /* cancel off-hook */
            }
        get_tm = biostime(0,0);           /* check Timeout counter */
        }
    while(get_tm <= end_tm && c_in_buf == 0) ;

    if(get_tm >= end_tm) return(TIMEOUT);  /* port timed out */

    ptr = outptr;
    c = *ptr++;                     /* Get next character in circular buff */
    if ( ptr == &buffer[CBS] )      /* Check for end of circular buffer */
        ptr = buffer;               /* start from bottom of buff */
    disable ( );                    /* no interrupts during pointer manips */
    outptr = ptr;                   /* set character output pointer */
    c_in_buf--;                     /* and decrement the character count */
    enable ( );                     /* then allow interrupts to continue */
    return ( c );                   /* Return the character */
}

void comm_flush ( )                 /* flushes all chars out of buffer */
{
    if ( xofsnt ) {                 /* Check if XON needs to be sent */
       xofsnt = 0;
       comm_putc ( XON );
    }
    disable ( );                    /* no interrupts during pointer manips */
    inptr = outptr = buffer;        /* reset buffer pointers */
    c_in_buf = 0;                   /* and indicate no chars received */
    enable ( );
}

void flsh_dtr ( )                   /* Drop DTR for 1/2 second */
{
    outportb( com8250 + 1, 0xa);    /* Un-set DTR (set RTS, OUT2) */
    delay(500);                     /* Wait for 1/2 second */
    outportb( com8250 + 1, 0xb);    /* Set DTR, RTS, OUT2 */

}


int carrier( )          /* TEST FOR CARRIER DETECT */
{

    delay(200);                     /* Short pause */
        if((inportb( MODEM_STAT ) & CARRIER_ON ) == CARRIER_ON)
        return(1);                  /* Check MSR for DCD */
        return(0);

}
main( int argc, char *argv[] )
{
   char result = 0;
   int port = 1;
   long speed = 12800l;      /* Default speed & port */
   char c=0;

   if( argc >= 2 ) port = *argv[1] - 48;
   if( argc == 3 ) speed = atol( argv[2] );

   cprintf ( "\r\n"
       "Serial port %d open at %ld baud\r\n"
           "hit \"ESC\" to exit\r\n\n", port, speed );

  if ( comm_open ( port, speed ) )
      {
        char RTSflag=0;
        while ( result != 27 && c != TIMEOUT)
       {
         if ( kbhit() )
          {               /* Check for keyboard press */

            if(!RTSflag)
             {
              outportb ( com8250 + 1, 0xb );
              result = getch();
//            printf("RTSflag=0 ");
              delay(10);
              if(result=='Q')RTSflag=1;
              if( result != 27 )  comm_putc ( result );
              delay(10);
              outportb ( com8250 + 1, 0x9 );
             }
             else
             {
                    outportb ( com8250 + 1, 0x9 );
                    result = getch();
//                  printf("RTSflag=1");
                    delay(10);
                    if(result=='q')RTSflag=0;
                    if( result != 27 )  comm_putc ( result );   /* If ! Escape */
                    delay(10);
                    outportb ( com8250 + 1, 0xb );
             }
           }                                           /* Output the char */
         if(comm_avail())
           {                             /* Is a char waiting? */
             c = comm_getc(3);
             switch ( c )
              {
               case '\t' :                            /* convert tabs */
                                for ( c = 0; c <100; c++ )
                                putch ( ' ' );
                                break;
               case TIMEOUT :                         /* check for timeout */
                                printf("\r\nPort Timed Out\r\n");  /* error */
                                break;
               default :
                         printf ("%c", c );                 /* put char to screen */
                         break;
               }
            }
      }

      printf("\nClosing Port %d\n",port);
      comm_close();
   }
   else
      printf ( "\r\nUnable to find port %d\r\n", port );
   return ( 0 );
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -