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

📄 commport.cpp

📁 dos下串口数据传输的基类
💻 CPP
字号:
// CommPort.cpp: implementation of the CCommPort class.
//
//////////////////////////////////////////////////////////////////////

#include "CommPort.h"
#include <string.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCommPortBasicClass::CCommPortBasicClass()
{
	m_PortBasicAddr=0;
	m_InterruptNo=0;
	m_BeSendingMark=0;

}
CCommPortBasicClass::~CCommPortBasicClass()
{
	if(!m_PortBasicAddr) return;
	disable();
	outportb(m_PortBasicAddr+1,0x0);  //禁止端口所有数据中断,不能缺少。
	setvect(m_InterruptNo,m_PortOldIntHandle);//恢复原中断
	//屏蔽中断IRQ
	if(m_InterruptNo>>4)
	{
		outportb(0x21,inportb(0x21)|~0xFB); //屏蔽中断IRQ2
		outportb(0xA1,inportb(0xA1)|(0x1<<(m_InterruptNo&0x07)));
	}
	else
	{
		outportb(0x21,inportb(0x21)|(0x1<<(m_InterruptNo&0x07)));
	}
	enable();
	delay(220);
}
//输入参数:端口基地址 端口中断号 期望的波特率 新中断处理函数
void CCommPortBasicClass::OpenCommPort(unsigned short int tPortBasicAddr,unsigned char tInterruptNo,unsigned short int tBaudRate,void interrupt (*tPortNewIntHandle)(...))
{
	if(!tPortBasicAddr||!tInterruptNo) return ;

	m_PortBasicAddr=tPortBasicAddr;//端口基地址
	m_InterruptNo=tInterruptNo;	//端口中断号
	m_BeSendingMark=0;

	disable();
	m_PortOldIntHandle=getvect(m_InterruptNo);   // 设置中断
	setvect(m_InterruptNo,tPortNewIntHandle);
		//取消中断IRQ的屏蔽
	if(m_InterruptNo>>4)
	{	//中断为从片IRQ
		outportb(0x21,inportb(0x21)&0xFB); //打开主片IRQ2
		outportb(0xA1,inportb(0xA1)&(~(0x1<<(m_InterruptNo&0x07))));//打开从片IRQ
	}
	else
	{//中断为主片IRQ
		outportb(0x21,inportb(0x21)&(~(0x1<<(m_InterruptNo&0x07))));//打开主片IRQ
	}

	//设置波特率为9600=115200/0xC,7200=115200/0x10..
	outportb(m_PortBasicAddr+3,0x80); //除数锁存器DLAB置1
	outportb(m_PortBasicAddr,(unsigned short int)(115200L/tBaudRate));//0xc=9600,0x10=7200..
	outportb(m_PortBasicAddr+1,0X0);  //始终为0

	outportb(m_PortBasicAddr+3,0x3); //设置数据格式,置DLAB=0:8位数据位,1位停止位,无校验
	outportb(m_PortBasicAddr+4,0xB);; //置UART操作方式为中断方式
	outportb(m_PortBasicAddr+1,0x0B);  //允许发送、接收数据中断
	enable();
}
void CCommPortBasicClass::PortIntHandleFunction()
{
	char ch;
	outportb(m_PortBasicAddr+3,inportb(m_PortBasicAddr+3)&0x7F); //置DLAB=0
	for( ; ;)
	{
		switch(inportb(m_PortBasicAddr+2))
		{
		case 1://已无其他中断
			if(m_InterruptNo>>4) outportb(0xA0,0x20);//向从片ICR送EOI命令
			outportb(0x20,0x20);//向主片ICR送EOI命令
			return ;
		case 2://发送中断
			if(SendQueue.GetData(ch)) outportb(m_PortBasicAddr,ch);
			else { m_BeSendingMark=0,inportb(m_PortBasicAddr+2);} // 不能缺少
			break;
		case 4://接收中断
			if(inportb(m_PortBasicAddr+5)&0x01)   //D0为1,有新数据
				ReceiveNewChar(inportb(m_PortBasicAddr)&0xFF);
			break;
		case 0://MODEM状态变化中断
			inportb(m_PortBasicAddr+6); // 不能缺少
			break;
		default:
			break;
		}
	}
}
void CCommPortBasicClass::ActiveSendInterrupt()
{
	if((!m_BeSendingMark)&&(m_PortBasicAddr))
	{
		char ch;
		m_BeSendingMark=1;
		SendQueue.GetData(ch);
		outportb(m_PortBasicAddr,ch);
	}
}
void CCommPortBasicClass::WriteStringToBuffer(char *str, unsigned short Len/*=0*/)
{
	if(Len==0) Len=strlen(str);
	for(unsigned short int i=0;i<Len;i++) SendQueue+=str[i];
	ActiveSendInterrupt();
}
void CCommPortBasicClass::WriteCharToBuffer(char ch)
{
	SendQueue+=ch;
	ActiveSendInterrupt();
}
int CCommPortBasicClass::ReadChar(char &ch)
{
	return RecvQueue.GetData(ch);
}
void CCommPortBasicClass::WriteStringToPort(char *str, unsigned short Len/*=0*/)
{
	if(Len==0) Len=strlen(str);
	for(unsigned short int i=0;i<Len;i++)  WriteCharToPort(str[i]);
}
void CCommPortBasicClass::WriteCharToPort(char ch)
{
	while((inportb(m_PortBasicAddr+5)& 0x20)==0)  //等待可以发送的信息,等待D5为1
	{// 超时处理部分,一般省略
	}
	outportb(m_PortBasicAddr,ch);
}
void CCommPortBasicClass::ReceiveNewChar(unsigned char ch)
{
	RecvQueue.AddData(ch);
}

void CCommPortBasicClass::EmptySendRecvBuffer()
{
	SendQueue.EmptyAll();
	RecvQueue.EmptyAll();
}

⌨️ 快捷键说明

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