?? commport.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); //禁止端口所有數(shù)據(jù)中斷,不能缺少。
setvect(m_InterruptNo,m_PortOldIntHandle);//恢復(fù)原中斷
//屏蔽中斷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);
}
//輸入?yún)?shù):端口基地址 端口中斷號 期望的波特率 新中斷處理函數(shù)
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); // 設(shè)置中斷
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
}
//設(shè)置波特率為9600=115200/0xC,7200=115200/0x10..
outportb(m_PortBasicAddr+3,0x80); //除數(shù)鎖存器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); //設(shè)置數(shù)據(jù)格式,置DLAB=0:8位數(shù)據(jù)位,1位停止位,無校驗
outportb(m_PortBasicAddr+4,0xB);; //置UART操作方式為中斷方式
outportb(m_PortBasicAddr+1,0x0B); //允許發(fā)送、接收數(shù)據(jù)中斷
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://發(fā)送中斷
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,有新數(shù)據(jù)
ReceiveNewChar(inportb(m_PortBasicAddr)&0xFF);
break;
case 0://MODEM狀態(tài)變化中斷
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) //等待可以發(fā)送的信息,等待D5為1
{// 超時處理部分,一般省略
}
outportb(m_PortBasicAddr,ch);
}
void CCommPortBasicClass::ReceiveNewChar(unsigned char ch)
{
RecvQueue.AddData(ch);
}
void CCommPortBasicClass::EmptySendRecvBuffer()
{
SendQueue.EmptyAll();
RecvQueue.EmptyAll();
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -