📄 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 + -