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

📄 rs232x3.cpp

📁 “TCP/IP协议库及例程”和“PPP-TCP/IP协议库及例程”系英创信息技术有限公司拥有自主知识产权之软件产品(软件产品登记证书号:川DGY-2004-0033)。上述软件的获得者仅允许将上述软件
💻 CPP
字号:
#include <dos.h>
#include "rs232x3.h"

#ifdef __cplusplus
    #define __CPPARGS ...
#else
    #define __CPPARGS
#endif

#define	THR	0
#define	RDR	0
#define	BRDL	0
#define	BRDH	1
#define	IER	1
#define	IIR	2
#define	FCR	2
#define	LCR	3
#define	MCR	4
#define	LSR	5
#define	MSR	6

#define	THR2	0
#define	RDR2	0
#define	BRDL2	0
#define	BRDH2	2
#define	IER2	2
#define	IIR2	4
#define	FCR2	5
#define	LCR2	6
#define	MCR2	8
#define	LSR2	10
#define	MSR2	12

#define IRQ4MaskBit	0x10
#define IRQ3MaskBit	0x08
#define IRQ6MaskBit	0x40
#define IRQ7MaskBit	0x80

#define	BUF_SIZE	1500

unsigned char InputBuf[3][BUF_SIZE];
unsigned int  IBufGetIdx[3];
unsigned int  IBufPutIdx[3];

unsigned char OutputBuf[3][BUF_SIZE];
unsigned int  OBufGetIdx[3];
unsigned int  OBufPutIdx[3];

unsigned int  ErrCNT = 0;

void interrupt ( *oldCOM1handler)(__CPPARGS);
void interrupt ( *oldCOM2handler)(__CPPARGS);
void interrupt ( *oldCOM3handler)(__CPPARGS);
void interrupt COM1_ISR(__CPPARGS);
void interrupt COM2_ISR(__CPPARGS);
void interrupt COM3_ISR(__CPPARGS);

int  BasePort[3]={ 0x3f8, 0xff80, 0xff10 };
int  PutInputData( int PortNum, char abyte );	// call by ISR
int  GetOutputData( int PortNum );			// call by ISR

// BaudIdx = 0:  230.4kbps ( only for COM2 COM3 )
// BaudIdx = 1:  115.2kbps
// BaudIdx = 2:  57.6kbps
// BaudIdx = 3:  38.4kbps
// BaudIdx = 6:  19.2kbps
// BaudIdx = 12: 9600bps
// BaudIdx = ...
// Parity = 0:  no   parity
//        = 1:  odd  parity
//        = 2:  even parity
int InitUART( int PortNum, unsigned int BaudIdx,  int Parity )
{
   int i1;
   unsigned int   tport;
   unsigned char  abyte;

   // check parameters
   switch( PortNum )
      {
      case COM1:
	   tport = 0x3f8;
	   if( BaudIdx==0 )    BaudIdx=1;
	   break;
      case COM2:
	   tport = 0xff80;
	   break;
      case COM3:
	   tport = 0xff10;
	   break;
      default:
	   return -1;
      }

   switch( Parity )
      {
      case 1:    abyte = 0x0b;      break;       // 8bit 1stop Odd_parity
      case 2:    abyte = 0x1b;      break;       // 8bit 1stop Even_parity
      default:   abyte = 0x03;      break;       // 8bit 1stop No_parity
      }
   if( PortNum==COM1 )
      {
      outportb(tport + LCR, 0x80);   // DLAB = 1, set baud reg access
      outportb(tport + BRDH, (BaudIdx>>8));
      outportb(tport + BRDL, BaudIdx);
      outportb(tport + LCR, abyte );
      //outportb(tport + FCR, 0);      // disable FIFO in 16C550
      outportb(tport + FCR, 0x87);     // enable FIFO in 16C550
      outportb(tport + IER, 0x03);      // set IER value
      outportb(tport + MCR, 0x0b);   // set MCR value

      i1 = inportb(tport + LSR);       // clear any line status interrupt
      if( i1==-1 )   return i1;
      inportb(tport + RDR);   	  // clear any receive interrupt
      inportb(tport + IIR);   	  // clear any transmitter interrupt
      inportb(tport + MSR);   	  // clear any modem status interrupt
      outportb(tport + IER, 0x05);
      }
   else
      {
      // for 96MHz:1.8432MHz baudrate
      if( BaudIdx==0 )   BaudIdx *= 26;
      else               BaudIdx *= 52;
      outport(tport + LCR2, 0x80);   // DLAB = 1, set baud reg access
      outport(tport + BRDH2, (BaudIdx>>8)&0x00ff);
      outport(tport + BRDL2, BaudIdx&0x00ff);
      outport(tport + LCR2, abyte );
      //outportb(tport + FCR2, 0);      // disable FIFO in 16C550
      outport(tport + FCR2, 0x87);     // enable FIFO in 16C550
      outport(tport + IER2, 0x03);      // set IER value
      outport(tport + MCR2, 0x0b);   // set MCR value

      i1 = inport(tport + LSR2);       // clear any line status interrupt
      if( i1==-1 )   return i1;
      inport(tport + RDR2);   	  // clear any receive interrupt
      inport(tport + IIR2);   	  // clear any transmitter interrupt
      inport(tport + MSR2);   	  // clear any modem status interrupt
      outport(tport + IER2, 0x05);
      }

   IBufGetIdx[PortNum] = 0;
   IBufPutIdx[PortNum] = 0;
   OBufGetIdx[PortNum] = 0;
   OBufPutIdx[PortNum] = 0;

   // finally check this UART controller
   if( PortNum==COM1 )
      if( (inportb(tport+LSR)&0xfe) != 0x60 ) return -2;
   else
      if( (inport(tport+LSR2)&0xfe) != 0x60 ) return -2;

   return 0;
}

void interrupt COM1_ISR(__CPPARGS)
{
   int             i1, i2;
   unsigned char   status;
   unsigned int    tport;

   enable( );

   tport = BasePort[COM1];
   status = inportb(tport + IIR) & 7;
   while( status != 1 )
      {
      switch (status)
	 {
	 case 0:                 // MODEM status change
	      inportb(tport + MSR);
	      break;
	 case 2:                 // THR empty
	      for( i2=0; i2<16; i2++ )
		 {
		 i1 = GetOutputData( COM1 );
		 if( i1 == -1 )    break;
		 outportb( tport+THR, i1 );
		 }
	      if( i2==0 )
		 outportb( tport+IER, inportb(tport+IER) & 0xd);
	      break;
	 case 4:                 // received data available
	 rxaga1:
	      PutInputData( COM1, inportb( tport+RDR ) );
	      if ( inportb(tport+LSR) & 0x01 )
		 goto  rxaga1;
	      break;
	 case 6:                 // receive status error
	      i1 = inportb(tport + LSR);
	      ErrCNT++;
	      break;
	 }
      status = inportb(tport + IIR) & 7;
      }

   outport( 0xff22, 0x0c );	// specific EOI command for IRQ4
}

void interrupt COM2_ISR(__CPPARGS)
{
   int            i1, i2;
   unsigned int   tport;
   unsigned int   status;

   enable( );

   tport = BasePort[COM2];
   status = inport(tport + IIR2) & 7;
   while( status != 1 )
      {
      switch (status)
	 {
	 case 0:                 // MODEM status change
	      inport(tport + MSR2);
	      break;
	 case 2:                 // THR empty
	      for( i2=0; i2<16; i2++ )
		 {
		 i1 = GetOutputData( COM2 );
		 if( i1 == -1 )       break;
		 outport( tport+THR2, i1 );
		 }
	      if( i2==0 )
		outport( tport+IER2, inport(tport+IER2) & 0xd);
	      break;
	 case 4:                 // received data available
	 rxaga2:
	      PutInputData( COM2, inport( tport+RDR2 ) );
	      if( inport( tport+LSR2 )&0x01 )
		 goto rxaga2;
	      break;
	 case 6:                 // receive status error
	      i1 = inport(tport + LSR2);
	      ErrCNT++;
	      break;
	 }
      status = inport(tport + IIR2) & 7;
      }

   outport( 0xff22, 0x0014 );	// specific EOI command
}


void interrupt COM3_ISR(__CPPARGS)
{
   int            i1, i2;
   unsigned int   status;
   unsigned int   tport;

   enable( );

   tport = BasePort[COM3];
   status = inport(tport + IIR2) & 7;
   while( status != 1 )
      {
      switch (status)
	 {
	 case 0:                 // MODEM status change
	      inport(tport + MSR2);
	      break;
	 case 2:                 // THR empty
	      for( i2=0; i2<16; i2++ )
		 {
		 i1 = GetOutputData( COM3 );
		 if( i1 == -1 )   break;
		 outport( tport+THR2, i1 );
		 }
	      if( i2==0 )
		 outport( tport+IER2, inport(tport+IER2) & 0xd);
	      break;
	 case 4:                 // received data available
	 rxaga3:
	      PutInputData( COM3, inport( tport+RDR2 ) );
	      if( inport( tport+LSR2 )&0x01 )
		 goto rxaga3;
	      break;
	 case 6:                 // receive status error
	      i1 = inport(tport + LSR2);
	      ErrCNT++;
	      break;
	 }
      status = inport(tport + IIR2) & 7;
      }

   outport( 0xff22, 0x0011 );	// specific EOI command
}

int GetOutputData( int PortNum )
{
   int i, i1;

   i1 = PortNum;

   if( OBufGetIdx[i1] != OBufPutIdx[i1] )
      {
      i = (int)OutputBuf[i1][OBufGetIdx[i1]];
      OBufGetIdx[i1] = ( OBufGetIdx[i1] + 1 ) % BUF_SIZE;
      return i;
      }
   return -1;
}

int PutOutputData( int PortNum, char abyte )
{
   unsigned int Idx;
   int i1;

   i1 = PortNum;

   if( OBufGetIdx[i1] == 0 ) Idx = BUF_SIZE - 1;
   else                  Idx = OBufGetIdx[i1] - 1;

   if( OBufPutIdx[i1] == Idx ) return -1;
   OutputBuf[i1][OBufPutIdx[i1]] = abyte;
   OBufPutIdx[i1] = ( OBufPutIdx[i1] + 1 ) % BUF_SIZE;
   return 0;
}

void StartSend( int PortNum )
{
   int i1;
   unsigned char aa;
   unsigned int  tport;

   tport = BasePort[PortNum];
   if( PortNum==COM1 )
      {
      aa = inportb(tport+IER);
      if( (aa&0x02) == 0 )
	 {
	 i1 = GetOutputData( PortNum );
	 if( i1 == -1 ) return;
	 outportb( tport+THR, (char)i1 );
	 outportb( tport+IER, aa|0x02 );	// enable THR interrupt
	 }
      }
   else
      {
      aa = inport(tport+IER2);
      if( (aa&0x02) == 0 )
	 {
	 i1 = GetOutputData( PortNum );
	 if( i1 == -1 ) return;
	 outport( tport+THR2, (char)i1 );
	 outport( tport+IER2, aa|0x02 );	// enable THR interrupt
	 }
      }
}

int PutInputData( int PortNum, char abyte )
{
   unsigned int Idx;
   int i1;

   i1 = PortNum;

   if( IBufGetIdx[i1] == 0 ) Idx = BUF_SIZE - 1;
   else                      Idx = IBufGetIdx[i1] - 1;

   if( IBufPutIdx[i1] == Idx ) return -1;
   InputBuf[i1][IBufPutIdx[i1]] = abyte;
   IBufPutIdx[i1] = ( IBufPutIdx[i1] + 1 ) % BUF_SIZE;
   return 0;
}

int GetInputData( int PortNum )
{
   int i;
   int i1;

   i1 = PortNum;

   if( IBufGetIdx[i1] != IBufPutIdx[i1] )
      {
      i = (int)InputBuf[i1][IBufGetIdx[i1]];
      IBufGetIdx[i1] = ( IBufGetIdx[i1] + 1 ) % BUF_SIZE;
      return i;
      }
   return -1;
}

int InstallISR( int PortNum )
{
   unsigned char MaskBit;

   switch( PortNum )
      {
      case COM1:
	   MaskBit = IRQ4MaskBit;
	   oldCOM1handler = getvect( 0x0c );
	   outportb( 0x21, inportb(0x21)|MaskBit );
	   setvect( 0x0c, COM1_ISR );
	   MaskBit = ~MaskBit;
	   outportb( 0x21, inportb(0x21)&MaskBit );
	   break;
      case COM2:
	   oldCOM2handler = getvect( 0x14 );
	   outport( 0xff44, inport(0xff44)|0x0008 );
	   setvect( 0x14, COM2_ISR );
	   outport( 0xff44, inport(0xff44)&0xfff7 );
	   break;
      case COM3:
	   oldCOM3handler = getvect( 0x61 );
	   outport( 0xff42, inport(0xff42)|0x0008 );
	   setvect( 0x61, COM3_ISR );
	   outport( 0xff42, inportb(0xff42)&0xfff7 );
	   break;
      default:
	   return -1;
      }

   return 0;
}

int UninstallISR( int PortNum )
{
   switch( PortNum )
      {
      case COM1:
	   setvect( 0x0c, oldCOM1handler );
	   break;
      case COM2:
	   outport( 0xff44, inport(0xff44)|0x0008 );
	   setvect( 0x14, oldCOM2handler );
	   break;
      case COM3:
	   outport( 0xff42, inport(0xff42)|0x0008 );
	   setvect( 0x61, oldCOM3handler );
	   break;
      default:
	   return -1;
      }

   return 0;
}

⌨️ 快捷键说明

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