VC++6.0怎么在程序中获取指定COM有数据传入的消息?(不使用MSCOMM控件哈)
(不使用MSCOMM控件哈)……该问题的产生主要是我读取数据是用的API函数,又要实现当有数据写入COM口时才读取,如果创建线程循环读取数据会导致CPU使用率过高。如果用...
(不使用MSCOMM控件哈)……该问题的产生主要是我读取数据是用的API函数,又要实现当有数据写入COM口时才读取,如果创建线程循环读取数据会导致CPU使用率过高。如果用自定义消息,可是怎么才让系统发消息给我说COM有数据写入了呢?如果答案满意,财富值可再加100,谢谢了,系统是win7
展开
展开全部
思路:
1,要建立一个线程,在线程中进行接收数据(没有收到数据线程是不占用CPU繁忙的)。
2,同时打开串口,设置超时,进行监听
3,如果有数据收到,或是超时后,会读到数据长度的(nBytesRead>0是有数据)
以下是读取关键代码
【相关的API函数】:
HANDLE hComm;
//串口设置
struct SERIAL_SETTING
{
COMMTIMEOUTS m_CommTimeouts;
OVERLAPPED m_ov;
DCB m_dcb;
}SerialSetting;
//1,关闭串口
void CloseCom(void)
{
if(hComm != NULL)
{
CloseHandle(hComm);
hComm = NULL;
}
}
//2,初始化串口
int OpenCom(unsigned char PortNo,
unsigned long BaudRate,
unsigned char Parity,
unsigned char ByteSite,
unsigned char StopBits)
{
char buf[1000];
char buffer[1000];
CloseCom();
if(SerialSetting.m_ov.hEvent != NULL)
{
ResetEvent(SerialSetting.m_ov.hEvent);
}
SerialSetting.m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SerialSetting.m_CommTimeouts.ReadIntervalTimeout = 100;
SerialSetting.m_CommTimeouts.ReadTotalTimeoutMultiplier = 100;
SerialSetting.m_CommTimeouts.ReadTotalTimeoutConstant = 100;
SerialSetting.m_CommTimeouts.WriteTotalTimeoutMultiplier = 100;
SerialSetting.m_CommTimeouts.WriteTotalTimeoutConstant = 100;
if(PortNo < 10)
{
sprintf(buf,"COM%d",PortNo);
}
else
{
sprintf(buf,"\\\\.\\COM%d",PortNo);
}
hComm = CreateFile(buf,GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if(hComm == INVALID_HANDLE_VALUE)
{
hComm = NULL;
return -1;
}
if(!SetCommTimeouts(hComm,&SerialSetting.m_CommTimeouts))
{
CloseCom();
return -1;
}
if(!SetCommMask(hComm,EV_RXCHAR))
{
CloseCom();
return -1;
}
//将dcb地址传入,以取得通信参数
if(!GetCommState(hComm,&SerialSetting.m_dcb))
{
CloseCom();
return -1;
}
SerialSetting.m_dcb.fRtsControl = RTS_CONTROL_DISABLE; // set RTS bit high!
SerialSetting.m_dcb.BaudRate = BaudRate; // 设置波特率为9600
SerialSetting.m_dcb.Parity = Parity; // Parity 为 None
SerialSetting.m_dcb.ByteSize = ByteSite; // 字节为 8 bit
SerialSetting.m_dcb.StopBits = StopBits; // 1 个Stop bit
//通信端口设置
if(!SetCommState(hComm, &SerialSetting.m_dcb)) // 设置通信端口的状态
{
CloseCom();
return -1;
}
if(!PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT))
{
CloseCom();
return -1;
}
}
return 1;
}
//3,读数据
int ReadData(void *pDataBuf,int &DataLen,unsigned int WaitTime)
{
bool bResult;
DWORD nBytesRead,dwError;
COMSTAT cs;
if(!ClearCommError(hComm,&dwError,&cs)) //取得状态
{
return -1;
}
//如果没有数据且不等待则返回错误
if(cs.cbInQue == 0 && WaitTime == 0)
{
return -1;
}
SerialSetting.m_ov.Offset = 0L;
SerialSetting.m_ov.OffsetHigh = 0L;
nBytesRead = 0;
dwError = 0;
bResult = ReadFile(hComm,pDataBuf,DataLen,&nBytesRead,&SerialSetting.m_ov); //接收通信端口的数据
if(!bResult)
{
dwError = GetLastError();
if(dwError != ERROR_IO_PENDING)
{
return -1;
}
if(WaitForSingleObject(SerialSetting.m_ov.hEvent,WaitTime) != WAIT_OBJECT_0)
{
return -1;
}
}
GetOverlappedResult(hComm,&SerialSetting.m_ov,&nBytesRead,TRUE);
if(nBytesRead <= 0)
{
return -1;
}
DataLen = nBytesRead;
}
return 1;
}
1,要建立一个线程,在线程中进行接收数据(没有收到数据线程是不占用CPU繁忙的)。
2,同时打开串口,设置超时,进行监听
3,如果有数据收到,或是超时后,会读到数据长度的(nBytesRead>0是有数据)
以下是读取关键代码
【相关的API函数】:
HANDLE hComm;
//串口设置
struct SERIAL_SETTING
{
COMMTIMEOUTS m_CommTimeouts;
OVERLAPPED m_ov;
DCB m_dcb;
}SerialSetting;
//1,关闭串口
void CloseCom(void)
{
if(hComm != NULL)
{
CloseHandle(hComm);
hComm = NULL;
}
}
//2,初始化串口
int OpenCom(unsigned char PortNo,
unsigned long BaudRate,
unsigned char Parity,
unsigned char ByteSite,
unsigned char StopBits)
{
char buf[1000];
char buffer[1000];
CloseCom();
if(SerialSetting.m_ov.hEvent != NULL)
{
ResetEvent(SerialSetting.m_ov.hEvent);
}
SerialSetting.m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SerialSetting.m_CommTimeouts.ReadIntervalTimeout = 100;
SerialSetting.m_CommTimeouts.ReadTotalTimeoutMultiplier = 100;
SerialSetting.m_CommTimeouts.ReadTotalTimeoutConstant = 100;
SerialSetting.m_CommTimeouts.WriteTotalTimeoutMultiplier = 100;
SerialSetting.m_CommTimeouts.WriteTotalTimeoutConstant = 100;
if(PortNo < 10)
{
sprintf(buf,"COM%d",PortNo);
}
else
{
sprintf(buf,"\\\\.\\COM%d",PortNo);
}
hComm = CreateFile(buf,GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if(hComm == INVALID_HANDLE_VALUE)
{
hComm = NULL;
return -1;
}
if(!SetCommTimeouts(hComm,&SerialSetting.m_CommTimeouts))
{
CloseCom();
return -1;
}
if(!SetCommMask(hComm,EV_RXCHAR))
{
CloseCom();
return -1;
}
//将dcb地址传入,以取得通信参数
if(!GetCommState(hComm,&SerialSetting.m_dcb))
{
CloseCom();
return -1;
}
SerialSetting.m_dcb.fRtsControl = RTS_CONTROL_DISABLE; // set RTS bit high!
SerialSetting.m_dcb.BaudRate = BaudRate; // 设置波特率为9600
SerialSetting.m_dcb.Parity = Parity; // Parity 为 None
SerialSetting.m_dcb.ByteSize = ByteSite; // 字节为 8 bit
SerialSetting.m_dcb.StopBits = StopBits; // 1 个Stop bit
//通信端口设置
if(!SetCommState(hComm, &SerialSetting.m_dcb)) // 设置通信端口的状态
{
CloseCom();
return -1;
}
if(!PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT))
{
CloseCom();
return -1;
}
}
return 1;
}
//3,读数据
int ReadData(void *pDataBuf,int &DataLen,unsigned int WaitTime)
{
bool bResult;
DWORD nBytesRead,dwError;
COMSTAT cs;
if(!ClearCommError(hComm,&dwError,&cs)) //取得状态
{
return -1;
}
//如果没有数据且不等待则返回错误
if(cs.cbInQue == 0 && WaitTime == 0)
{
return -1;
}
SerialSetting.m_ov.Offset = 0L;
SerialSetting.m_ov.OffsetHigh = 0L;
nBytesRead = 0;
dwError = 0;
bResult = ReadFile(hComm,pDataBuf,DataLen,&nBytesRead,&SerialSetting.m_ov); //接收通信端口的数据
if(!bResult)
{
dwError = GetLastError();
if(dwError != ERROR_IO_PENDING)
{
return -1;
}
if(WaitForSingleObject(SerialSetting.m_ov.hEvent,WaitTime) != WAIT_OBJECT_0)
{
return -1;
}
}
GetOverlappedResult(hComm,&SerialSetting.m_ov,&nBytesRead,TRUE);
if(nBytesRead <= 0)
{
return -1;
}
DataLen = nBytesRead;
}
return 1;
}
更多追问追答
追问
我的做法是建立了一个线程,去监控串口,如果发生事件则在该线程中读取数据,然后继续该线程:
监控代码下,eol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); //设置eol.hEvent为无信号状态为无信号状态后
while{
waitCommEvent(hComm,&dwEvtMask,&eol);
dwRes=WaitForSingleObject(eol.hEvent,INFINITE);
发生的问题是/一直都未获取到eol.hEvent的有消息状态,也就是无法进入dwRes值的判断……
追答
你在线程中循环调用ReadData即可,返回1就是读到了,如果没有则在循环中继续读.
WaitTime 是超时时间。跟据接收数据大小设置,一般100-500ms。
读到的数据就从线程中以消息方式把数据发出去。
int ReadData(void *pDataBuf,int &DataLen,unsigned int WaitTime)
//pDataBuf :接收数组
//DataLen :返回接收到的数组长度
//WaitTime :读超时(如果超过时间段没有读到,则不再等待,返回;如果在时间段内读到,则马上返回)
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询