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

📄 rs485.cpp

📁 英创386模块的RS485控制协议和函数,还有例程
💻 CPP
字号:
#include <dos.h>
#include "rs485.h"

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

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

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

#define	BUF_SIZE	1500

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

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

void interrupt ( *oldCOMhandler)(__CPPARGS);
void interrupt COM_ISR(__CPPARGS);

unsigned int  tport;
int  PutInputData( char abyte );	// call by ISR
int  GetOutputData( );			// call by ISR

// BaudIdx = 1:  115.2kbps
// BaudIdx = 2:  57.6kbps
// BaudIdx = 3:  38.4kbps
// BaudIdx = 6:  19.2kbps
// BaudIdx = 12: 9600bps
// BaudIdx = ...
int InitUART( int PortNum, unsigned int BaudIdx )
{
   int i1;

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

   // for 96MHz:1.8432MHz baudrate
   BaudIdx *= 52;
   outport(tport + LCR, 0x80);   // DLAB = 1, set baud reg access
   outport(tport + BRDH, (BaudIdx>>8)&0x00ff);
   outport(tport + BRDL, BaudIdx&0x00ff);
   outport(tport + LCR, 0x03);   // 8bit 1stop No_parity
   outport(tport + IER, 0);   	  // set IER value
   outport(tport + MCR, 0x0b);   // set MCR value
   outport(tport + IIR, 0);	  // disable FIFO of 16550, if existed

   inport(tport + LSR);          // clear any line status interrupt
   inport(tport + RDR);   	  // clear any receive interrupt
   inport(tport + IIR);   	  // clear any transmitter interrupt
   inport(tport + MSR);   	  // clear any modem status interrupt
   outport(tport + FCR, 0);      // disable FIFO in 16C550
   outport(tport + IER, 0x01);

   IBufGetIdx = 0;
   IBufPutIdx = 0;
   OBufGetIdx = 0;
   OBufPutIdx = 0;

   return 0;
}

void interrupt COM_ISR(__CPPARGS)
{
   int            i1;
   unsigned int   status;

   enable( );

   status = inport(tport + IIR) & 7;
   while( status != 1 )
      {
      i1 = inport(tport + LSR);
      switch (status)
	 {
	 case 0:                 // MODEM status change
	      inport(tport + MSR);
	      break;
	 case 2:                 // THR empty
	 lab4:
	      i1 = GetOutputData( );
	      if( i1 != -1 ) outport( tport+THR, i1 );
	      else           outport( tport+IER, inport(tport+IER) & 0xd);
	      break;
	 case 4:                 // received data available
	      PutInputData( inport( tport+RDR ) );
	      break;
	 case 6:                 // Line status change
	      break;
	 }
      status = inport(tport + IIR) & 7;
      }

   // These ugly two lines are here because some PC clones will not give you the
   // THR empty interrupt if there is a simultaneous RX available interrupt.
   if( (inport(tport + IER)&2) && (inport(tport + LSR) & 0x20) )
       goto lab4;

   switch( tport )
      {
      case 0xff80:			// COM2
	   outport( 0xff22, 0x0014 );	// specific EOI command
	   break;
      case 0xff10:
	   outport( 0xff22, 0x0011 );	// specific EOI command
	   break;
      }
}

int GetOutputData( )
{
   int i;

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

int PutOutputData( char abyte )
{
   unsigned int Idx;

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

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

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

   aa = inport(tport+IER);
   if( (aa&0x02) == 0 )
      {
      i1 = GetOutputData( );
      if( i1 == -1 ) return;
      outport( tport+THR, (char)i1 );
      outport( tport+IER, aa|0x02 );	// enable THR interrupt
      }
}

int PutInputData( char abyte )
{
   unsigned int Idx;

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

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

int GetInputData( )
{
   int i;

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

int InstallISR( int PortNum )
{
   unsigned char MaskBit;

   switch( PortNum )
      {
      case COM2:
	   oldCOMhandler = getvect( 0x14 );
	   outport( 0xff44, inport(0xff44)|0x0008 );
	   setvect( 0x14, COM_ISR );
	   outport( 0xff44, inport(0xff44)&0xfff7 );
	   break;
      case COM3:
	   oldCOMhandler = getvect( 0x61 );
	   outport( 0xff42, inport(0xff42)|0x0008 );
	   setvect( 0x61, COM_ISR );
	   outport( 0xff42, inportb(0xff42)&0xfff7 );
	   break;
      default:
	   return -1;
      }

   return 0;
}

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

   return 0;
}

⌨️ 快捷键说明

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