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

📄 stdcom.cpp

📁 这是一段在DOS下通过中断方式实现的串行口收发程序。使用环境为DOS下的C++..使用者只需将stdcom.cpp和stdcom.h加入自己的工程中即可。
💻 CPP
字号:
#include <dos.h>
#include <string.h>
#include <stdio.h>
#include <alloc.h>
#include "StdCom.h"
#define __CPPARGS ...


BYTE   COM2 = 0x0b;          // Interrupt vector
WORD   PORT2 = 0x2f8 ;       // Port address
struct TranslateStruct Com2Send ;
struct TranslateStruct Com2Receive ;


				 // Save COM interrupt address
void interrupt (* OldCOM2Handler) (__CPPARGS) ;
				 // New COM interrupt address
void interrupt COM2Handler (__CPPARGS) ;
void Com2InterruptReceive (void) ;
void Com2InterruptSend (void) ;


void interrupt COM2Handler (__CPPARGS)
{
	asm cli
	int intstatus ;
	intstatus = inportb (PORT2 + 2) ;
	while (! (intstatus & 0x1))
	{
		if (intstatus == 4)
			Com2InterruptReceive ( ) ;
		if (intstatus == 2)
			Com2InterruptSend ( ) ;
		intstatus = inportb(PORT2 + 2);
	}
	asm mov al, 20h
	asm out 20h, al
	asm sti
}

void Com2InterruptReceive (void)
{
	// Read receive data into receive buffer
	Com2Receive.Buffer [Com2Receive.Counter] = inportb (PORT2) ;
	Com2Receive.Counter ++ ; // Adjust Receive counter
	if(Com2Receive.Counter >= MaxLength)
		Com2Receive.Counter = 0 ;
}

void Com2InterruptSend (void)
{
	// Send data interrupt process
	outportb (PORT2, Com2Send.Buffer [Com2Send.Counter]) ;
	Com2Send.Counter ++ ;

	if(Com2Send.Counter >= Com2Send.Length)
	{
		outportb (PORT2 + 1,0x01);
		Com2Send.Length = 0;
		Com2Send.Counter = 0 ;
	}
}

CStdCOM :: CStdCOM (int comId=1, long baud=9600, BYTE mode=0x03)
{
	ComId = comId ;
	Baud = baud ;
	Mode = mode;

//------------add by cfy 98.8.28
	if (ComId == 1)
	{
	}
	else
	{
		OldCOM2Handler = getvect(COM2);  	// save the old interrupt vector
		setvect(COM2, COM2Handler);    	// install the new interrupt handler
		Old8250IntMask = inportb (0x21) ;
	}
//------------------------add end------------------------
}

CStdCOM :: ~CStdCOM ( )
{
	CloseComm ( );
}

CStdCOM :: CloseComm ( )
{
	if (ComId == 1)
	{
	}
	else
	{
		// reset the old interrupt handler
		setvect(COM2, OldCOM2Handler);
		outportb (0x21, Old8250IntMask) ;
	}
	return 0 ;
}

/*
	Function : Initinate COM1 or COM2 port : 8 data bits, 1 stop bit ,
	 no check bit . Baud is enable to choose .
	 Working with interrupts mode, there is two kind of interrupt
	 mode : receive and send .

	Enter parameters :
	 Port : COM start port : 0x2F8 or 0x3F8    */

//void    CStdCOM :: InitComm (void)   change by cfy 98.8.28

void CStdCOM :: InitComm (WORD combaud)
{
	Baud=combaud;
	int Port ;
	if (ComId == 1)
	{
	}
	else
	{
		memset (&Com2Receive, 0, sizeof (struct TranslateStruct));
		memset (&Com2Send, 0, sizeof (struct TranslateStruct));
		Port = PORT2 ;
	}
	inportb (Port);
	disable ( );
	BYTE highbyte,lowbyte;
	WORD baud;
	if (Baud != 0) baud=(WORD)((long)(300L*0x180L)/Baud);
	highbyte = baud >> 8;
	lowbyte = baud & 0xff;

	disable();
	outportb (Port + 3, Mode) ;
	outportb (0x21, 0x0ff) ;

	Com2Send.Length = 0 ;
	Com2Send.Counter = 0 ;
	Com2Receive.Length = 0 ;
	Com2Receive.Counter = 0 ;
	Com2Receive.FetchCounter = 0 ;

	outportb (Port + 1, 0x01) ;
	// Set interrupt enable register  Addres :   COM1 : 3F9  COM2 : 2F9

	outportb (Port + 4, 0x0b) ;
	// Set MODEM control register enable  Address : COM1 : 3FC   COM2 : 2FC

	outportb (Port + 3, 0x80) ;
	// Set DLAB = 1
	// Set translation control register  Addres :   COM1 : 3FB  COM2 : 2FB

	outportb (Port + 1, highbyte) ;
	// Set Baud register high byte  Addres :   COM1 : 3F9  COM2 : 2F9

	outportb (Port, lowbyte) ;
	// Set Baud register low byte  Addres :   COM1 : 3F8  COM2 : 2F8

	outportb (Port + 3, Mode) ;
 //  outportb (Port + 3, 0x07) ;
	// Set data format : 1 stop bit 8 data bits
	// Addres :   COM1 : 3FB  COM2 : 2FB
	// DataBITS: Bit1 Bit0 = 00 5Bits; = 10 6Bits; = 01 7Bits; = 11 8Bits.
	// StopBITS: Bit2 = 0 1Bits; = 1 2Bits.
	// Check: Bit5 Bit4 Bit4 = 000 NONE; = 100 ODD ; = 110 EVEN;
	//        = 101 MARK; = 111 SPACE.
	outportb (0x21, 0x0) ;
	inportb(Port);
	inportb(Port);
	enable ( ) ;
}

int CStdCOM:: StdComSendData (BYTE * buf, int length)
{
	if(ComId == 1)
	{
	}
	else
	{
		if (Com2Send.Counter < Com2Send.Length)
			return  1 ;                       // All Data is not sent yet
		if (length >= MaxLength || length <= 0)
			return  2 ;                       // Data is too long or < 0

		for(int i = 0; i < length; i ++)        // Store data into send buffer
			Com2Send.Buffer[i] = buf [i] ;

		Com2Send.Length = length ;               // Set Send length
		Com2Send.Counter = 0 ;                   // Clear Send counter
		outportb (PORT2 + 1, 0x03) ;          // Open Send enable register
	}
	return 0 ;  // Send sucessfully
}

int  CStdCOM :: ReadData (BYTE * buf)
{
	struct TranslateStruct * pRecv;

	if (ComId == 2)
		pRecv = & Com2Receive ;
	int i=0;
	asm cli
	while(pRecv->FetchCounter != pRecv->Counter)
	{
		buf [i] = pRecv->Buffer [pRecv->FetchCounter] ;
		i ++ ;
		pRecv->FetchCounter ++ ;
		if (pRecv->FetchCounter >= MaxLength)
			pRecv->FetchCounter = 0 ;
	}
	asm sti
	return i ;
}

void CStdCOM :: ClearBuffer (int flag)
{
	asm cli
	if (ComId == 1)
	{
	}
	else
	{
		if(flag==0)
		{
			Com2Receive.Length = 0 ;
			Com2Receive.Counter = 0 ;
			Com2Receive.FetchCounter = 0 ;
			outportb (PORT2 + 1, 0x01) ;
		}
		else if(flag==1)
		{
			Com2Send.Length = 0 ;
			Com2Send.Counter = 0 ;
			outportb (PORT2 + 1, 0x01) ;
		}
		else if(flag==2)
		{
			Com2Receive.Length = 0 ;
			Com2Receive.Counter = 0 ;
			Com2Receive.FetchCounter = 0 ;
			Com2Send.Length = 0 ;
			Com2Send.Counter = 0 ;
			outportb (PORT2 + 1, 0x01) ;
			inportb(PORT2);
		}
	}
	asm sti
}

int 	CStdCOM :: ReceiveChar (BYTE * cBuf)
{
	struct TranslateStruct * pRecv;

	if (ComId == 2)
		pRecv = &Com2Receive ;

	if (pRecv->FetchCounter == pRecv->Counter)
		return 0 ;
	asm cli
	*cBuf = pRecv->Buffer [pRecv->FetchCounter] ;

	pRecv->FetchCounter ++ ;
	if (pRecv->FetchCounter >= MaxLength)
		pRecv->FetchCounter = 0 ;
	asm sti

	return 1 ;
}


int CStdCOM :: SendBlock (BYTE * buf, int length)
{
	while (1)
	{
		if (StdComSendData (buf, length) == 0)
			return length;
	}
}

⌨️ 快捷键说明

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