串口通信被定时器干扰的问题!请帮忙分析一下!谢谢!
我现在程序中有串口通信事件中断方式接收数据,下位机收到命令后就会发数据过来,我的主控板接收下位机的数据完成后会通过发送消息的方式来重新发送命令数据给下位机,这样实现循环发送接收,定时器会定时更新某个显示控件,与串口通信无关!现在的问题是:如果我不打开定时器,串口通信可以一直正常工作,但当我打开定时器以后,串口通信总是不时的出现丢数据的现象,我想问一下,串口通信跟定时器有什么关系,为什么会出现这种干扰现象?
这是串口接收数据程序:
DWORD WINAPI ReadPortThread(LPVOID lpvoid)
{
BOOL fReadState;
DWORD dwCommModemStatus;
DWORD dwLength;
COMSTAT ComStat;
DWORD dwErrorFlags;
CString strTmp;
CString string;
COMADlg* p=(COMADlg*)lpvoid;//获得窗口的指针
while(hPort!=INVALID_HANDLE_VALUE)
{
WaitCommEvent (hPort, &dwCommModemStatus, 0);
if (dwCommModemStatus & EV_RXCHAR)
{
Sleep(100);
ClearCommError(hPort,&dwErrorFlags,&ComStat);
dwLength=ComStat.cbInQue;
if(dwLength > 0)
{
BYTE* buf=new BYTE[8256];
fReadState=ReadFile(hPort,buf,dwLength,&dwLength,NULL);
if(!fReadState)
{
MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
}
else
{
for(WORD i=0;i<dwLength;i++)
{
CCD_Data[receive_count+i] = buf[i];
}
receive_count+=dwLength;
if(receive_count>=2047)
{
string.Format (_T("\n%d"),receive_count);
TRACE(string);
if(receive_count==2047
{
}
else if(receive_count>2047)
s2440IOP->rGPBDAT = (s2440IOP->rGPBDAT |0x01);
receive_count = 0;
//PurgeComm(hPort,PURGE_RXCLEAR);
p->SendMessage(WM_RECEIVED);
}
}
delete[] buf;
}
}
GetCommModemStatus (hPort, &dwCommModemStatus);
}
return 0;
}
下面是定时器程序部分:
void COMADlg::OnTimer(UINT nIDEvent)
{
m_data++;
mr_NO2nd = m_data;
mr_NOnd = m_data;
mr_SO2nd = m_data;
SetDlgItemInt(IDC_NDSO2,mr_SO2nd);
SetDlgItemInt(IDC_NDNO2,mr_NO2nd);
SetDlgItemInt(IDC_NDNO,mr_NOnd);
CDialog::OnTimer(nIDEvent);
}
请各位大侠帮帮忙 ,小弟感激不尽!我实在不知道原因!
[解决办法]
按理来说不会有这种问题呀,你试着创建一个线程来代替定时器试一下。
[解决办法]
// 试着将串口超时设置的长一些看看。
[解决办法]
和定时器有啥关系。。。单开定时器,不创建线程,用串口调试工具看看会不会有同样现象
[解决办法]
有关系吗??????
[解决办法]
WINCE是不怎么样,但也不至于串口都不稳定
给你我在EVC上写的串口类
#ifndef __COMMSERIAL_H__
#define __COMMSERIAL_H__
#include <windows.h>
#define INI_COM_T("COM4:")
#define INI_TIME_OUT3
class CCommSerial
{
public:
// constructor
CCommSerial(CString sPort = INI_COM,
DWORD dwBaudRate = 115200,
BYTE bDataBits = 8,
BYTE bStopBits = 0,
BYTE bParity = 0,
DWORD dwTimeOut = 50);
// destructor
~CCommSerial();
BOOL Open();
BOOL Close();
BOOL Setup();
BOOL WaitRevEvent();
DWORD ReadBuffer(BYTE* buffer, DWORD dwToRead);
DWORD WriteBuffer(const BYTE* buffer, DWORD dwToWrite);
BOOL ClearReadBuffer();
BOOL ClearWriteBuffer();
BOOL m_bConnected;
private:
DWORD m_dwTimeOut;
DWORD m_dwBaudRate;
BYTE m_bDataBits;
BYTE m_bStopBits;
BYTE m_bParity;
CString m_sPort;
HANDLE m_hComm;
};
#endif // __COMMSERIAL_H__
#include "stdafx.h"
#include "CommSerial.h"
CCommSerial::CCommSerial(CString sPort /* = "COM4:" */,
DWORD dwBaudRate /* = 115200 */,
BYTE bDataBits /* = 8 */,
BYTE bStopBits /* = 0 */,
BYTE bParity /* = 0 */,
DWORD dwTimeOut /* = 50 */) :
m_sPort(sPort), m_dwBaudRate(dwBaudRate),
m_bDataBits(bDataBits), m_bStopBits(bStopBits),
m_bParity(bParity), m_dwTimeOut(dwTimeOut)
{
m_bConnected = FALSE;
if (Open())
if (Setup())
m_bConnected = TRUE;
}
CCommSerial::~CCommSerial()
{
if (m_hComm != INVALID_HANDLE_VALUE)
Close();
}
BOOL CCommSerial::Open()
{
// Open the serial communicate device
m_hComm = CreateFile(
m_sPort,
GENERIC_READ
[解决办法]
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (m_hComm == INVALID_HANDLE_VALUE)
return FALSE;
return TRUE;
}
BOOL CCommSerial::Setup()
{
COMMTIMEOUTS timeouts;
DCB dcb;
// Set the timeout parameters. Set ReadTotalTimeoutConstant
// and ReadTotalTimeoutMultiplier to 0 will lead to ReadFile
// operation immediately return and completely operate
timeouts.ReadIntervalTimeout = m_dwTimeOut;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 50;
timeouts.WriteTotalTimeoutConstant = 300;
if (!SetCommTimeouts(m_hComm, &timeouts))
return FALSE;
// Get the specified comm status
if (!GetCommState(m_hComm, &dcb))
return FALSE;
dcb.BaudRate = m_dwBaudRate;
dcb.ByteSize = m_bDataBits;
switch (m_bStopBits)
{
case 0:
dcb.StopBits = ONESTOPBIT;
break;
case 1:
dcb.StopBits = ONE5STOPBITS;
break;
case 2:
dcb.StopBits = TWOSTOPBITS;
break;
default:
dcb.StopBits = ONESTOPBIT;
break;
}
switch (m_bParity)
{
case 0:
dcb.Parity = NOPARITY;
dcb.fParity = FALSE;
break;
case 1:
dcb.Parity = ODDPARITY;
dcb.fParity = TRUE;
break;
case 2:
dcb.Parity = EVENPARITY;
dcb.fParity = TRUE;
break;
case 3:
dcb.Parity = MARKPARITY;
dcb.fParity = TRUE;
break;
case 4:
dcb.Parity = SPACEPARITY;
dcb.fParity = TRUE;
break;
default:
dcb.Parity = NOPARITY;
dcb.fParity = FALSE;
break;
}
// Set the specified comm status
if (!SetCommState(m_hComm, &dcb))
return FALSE;
// Initialize the communications parameters
if (!SetupComm(m_hComm, 2048, 1024))
return FALSE;
// Clear the comm buffer
if (!PurgeComm(m_hComm, PURGE_RXCLEAR
[解决办法]
PURGE_TXCLEAR
[解决办法]
PURGE_RXABORT
[解决办法]
PURGE_TXABORT))
return FALSE;
return TRUE;
}
BOOL CCommSerial::Close()
{
COMSTAT ComStat;
DWORD dwError;
if (m_hComm != INVALID_HANDLE_VALUE)
{
ClearCommError(m_hComm, &dwError, &ComStat);
if (!CloseHandle(m_hComm))
return FALSE;
m_bConnected = FALSE;
}
return TRUE;
}
BOOL CCommSerial::WaitRevEvent()
{
COMSTAT ComStat;
DWORD dwEvtMask;
DWORD dwError;
if (!SetCommMask(m_hComm, EV_RXCHAR))
return FALSE;
if (!WaitCommEvent(m_hComm, &dwEvtMask, NULL))
{
ClearCommError(m_hComm, &dwError, &ComStat);
return FALSE;
}
return TRUE;
}
DWORD CCommSerial::ReadBuffer(BYTE* buffer, DWORD dwToRead)
{
DWORD dwReaded = 0;
COMSTAT ComStat;
DWORD dwError;
ClearCommError(m_hComm, &dwError, &ComStat);
ReadFile(m_hComm, buffer, dwToRead, &dwReaded, NULL);
return dwReaded;
}
DWORD CCommSerial::WriteBuffer(const BYTE* buffer, DWORD dwToWrite)
{
DWORD dwWritted = 0;
COMSTAT ComStat;
DWORD dwError;
ClearCommError(m_hComm, &dwError, &ComStat);
WriteFile(m_hComm, buffer, dwToWrite, &dwWritted, NULL);
return dwWritted;
}
// Clear the read buffer
BOOL CCommSerial::ClearReadBuffer()
{
return PurgeComm(m_hComm, PURGE_RXCLEAR);
}
// Clear the write buffer
BOOL CCommSerial::ClearWriteBuffer()
{
return PurgeComm(m_hComm, PURGE_TXCLEAR);
}
[解决办法]
在你的主程序中:
m_pComm = new CCommSerial(m_strComPort);
if (m_pComm && m_pComm->m_bConnected)
创建线程;
线程中:
m_pComm->WaitRevEvent()然后m_pComm->ReadBuffer()
[解决办法]
可以排除是下位机的问题喽?
[解决办法]
感觉丢数据不应该啊,因为是数据处理完成之后发送命令,串口才会发送数据,完全有时间处理完数据。楼主可以试着把每次接收到得数据字节数 receive_count 显示出来,看看数据的接收情况,是不是会出现接收数据断断续续的现象,我在使用蓝牙的虚拟串口的时候就出现过类似问题。
[解决办法]
断断续续的意思就是receive_count应该是增加的,但是在增加到某个值的时候会停止,然后继续增加,最后的值达不到2047.串口接收一次收不了2047也很正常啊,多读几次就可以了。
另外试试不要使用waitCommEvent,直接从这里开始
BYTE* buf=new BYTE[2048];
fReadState=ReadFile(hPort,buf,2048,&dwLength,NULL);
[解决办法]
路过看看.........