wince下串口问题,平时数据传输正常,但鼠标反复点击移动有时就会使串口数据错误,或者是界面切换时。我感觉是系统忙了有时会影响串口读取。波特率的57600,不算很高吧?缓冲区我也设置的很大了。数据没有丢失,只是出现错误。例如我发送端发的全是0,但系统忙时突然跳出个1或其他数来。,请大家帮分析一下可能是什么问题?
驱动有问题吧,以前碰到的一次,竟然是驱动的问题,换一个驱动就好了.
不管如何:
仔细看看代码,先确保代码没有问题.
程序有问题
接收是需要时间的
系统繁忙的时候CPU忙不过来,所以产生了乱码,加个延时就不会了
ppzzhhsky :我在接收线程中加了Sleep(50),还是不管用。
换一个设备或板子试试。
如果还是有问题,最好贴你的接受/发送的代码出来。
串口传输不会这么不稳定的。经过多少年实际使用的东西了。
最大问题还是你的代码。
DWORD WINAPI CPSerialPort::ReadPortThread(LPVOID lpParameter)
{
CPSerialPort* m_pSerial;
m_pSerial=(CPSerialPort*)lpParameter;
BOOL fReadState;
DWORD dwCommModemStatus;
DWORD dwLength;
COMSTAT ComStat;
DWORD dwErrorFlags;
unsigned char* buf=new unsigned char[m_pSerial->m_nBufferSize];
try
{
while((m_pSerial->m_hComm!=INVALID_HANDLE_VALUE)&&(m_pSerial->m_bReceiving))
{
WaitCommEvent(m_pSerial->m_hComm,&dwCommModemStatus,0);
if(dwCommModemStatus & EV_RXCHAR)
{
ClearCommError(m_pSerial->m_hComm,&dwErrorFlags,&ComStat);
SetCommMask (m_pSerial->m_hComm, EV_RXCHAR);
dwLength=ComStat.cbInQue;
if(dwLength>0)
{
fReadState=ReadFile(m_pSerial->m_hComm,buf,dwLength,&dwLength,NULL);
if(!fReadState)
{
AfxMessageBox(_T("无法从串口读取数据!"));
}
else
{
if(dwLength!=0)
{
//回送数据
if(m_pSerial->m_lpDataArriveProc!=NULL)
{
m_pSerial->m_lpDataArriveProc(buf,dwLength,m_pSerial->m_dwUserData);
}
}
}
}
}
Sleep(100);
}
delete[] buf;
}
catch(...)
{
AfxMessageBox(_T("MotherReadPortThread"));
}
return 0;
}
接收的数据存到了一个数组队列里。另一个线程解析队列里的数据。只要鼠标一动,解析数据的函数就报错,原因就是接收的数据出错了,不符合协议规定的格式了。线程同步也做了,用的临界区。
换了块板子,重做了内核,还是有错误。串口驱动用的是厂家给的。用的英贝德公司的SBC-9307的板子。
ppzzhhsky说让加个延时时我才加上的,加不加都不管用。
我开始是没有Sleep(100); 这句的。
现在程序自己跑只要鼠标不动跑一两个小时都不出错,但一动鼠标马上就出错。
m_pSerial-> m_lpDataArriveProc(buf,dwLength,m_pSerial-> m_dwUserData);
你把这行处理数据的代码注释掉。移动鼠标有问题吗?
把m_pSerial-> m_lpDataArriveProc(buf,dwLength,m_pSerial-> m_dwUserData); 注释掉串口数据接收不了,当然不会出错啦。
m_lpDataArriveProc是指向函数OnDataArriveMother的指针
void CMonitorDlg::OnDataArriveMother(unsigned char *data,int length,DWORD userdata)
{
CMonitorDlg *pWnd=(CMonitorDlg *)userdata;
::SendMessage(pWnd->m_hWnd,WM_NEW_DATA_ARRIVE_MOTHER,(WPARAM)data,LPARAM(length));
}
OnDataArriveMother把串口数据通过消息发送给主窗口。消息处理函数是:
void CMonitorDlg::OnMotherDataArrivedMsg(WPARAM wParam,LPARAM lParam)
{
//处理收到的数据
int length=(int)lParam;
unsigned char *data=(unsigned char*)wParam;
MotherBufferIn(length,data);
}
MotherBufferIn把串口数据存到我自己定义的队列。同时另外一个线程读取队列里的数据进行分析,画图。
我现在考虑一个问题:两个线程同时访问队列,我加了临界区同步。如果此时分析画图线程正在读取队列,队列被加锁,正好过来了串口来数据的消息,队列还能更新数据么?也就是说线程能够挂起,消息能挂起吧?
我初步感觉是你的接受线程和主线程的关系太紧密了。
你把处理数据的函数能否都和主线程脱离开。只是在必须的时候才postmessage给主线程。
你的SendMessage会有问题的。它是必须等到OnMotherDataArrivedMsg处理完才返回的。
系统繁忙会导致露接数据或者数据发送延误,这些可以理解.但是一定不会造成数据错误.我也认为是驱动的问题
问题解决多谢lenux,是发消息的问题。直接在OnDataArriveMother里处理数据,没必要再发消息。