串口接收数据的问题!!

fjw666 2010-07-09 03:38:26
我用的是异步接收串口数据,该线程通过循环调用WaitCommEvent函数来检测串口状态,当发现有数据时,调用ReadFile函数读取数据,并触发给回调函数,由此实现串口数据的实时异步读取。
当然这个串口函数我是借用别人的,不是自己编写的。
但是我现在想做的修改是:当判断串口有数据的时候,发送消息,并通知去取缓存中的数据,但是又只是取出里面的一个数据而已。目前我这个程序是一次性把缓存里面的数据都取出来了,给数据的读取显示带来很多麻烦,怎么办?
谢谢各位了
...全文
232 点赞 收藏 7
写回复
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
fjw666 2010-07-13
[Quote=引用 6 楼 lfchen 的回复:]
// ceSeries->m_OnSeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
// 你看一下这个函数的实现,找到ReadFile,将ReadFile的第三个参数改为1就行。
// 其实不建议这样做。如果通讯数据量大的话,很可能造成串口缓冲区溢出。
// 可以将全部数据都读到一个数组中,然后你去处理这个数组。
[/Quote]

搞不懂啊。郁闷惨了。其实你的意思我是明白的,但是真正操作起来无法解决
回复
// ceSeries->m_OnSeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
// 你看一下这个函数的实现,找到ReadFile,将ReadFile的第三个参数改为1就行。
// 其实不建议这样做。如果通讯数据量大的话,很可能造成串口缓冲区溢出。
// 可以将全部数据都读到一个数组中,然后你去处理这个数组。
回复
yimins 2010-07-09
不懂C语言,不过我最近也在研究这个,我估计可以用api 函数ReadFile 的参数来解决这个问题。

检测到串口数据到达之后,调用ReadFile 函数读取数据

BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);


其中第三个参数传入实际需要读取的字节数,你如果想一个个字节读取,可以设置为1。

不过另外提醒楼主一句,你不将数据读取完的话,下次新数据到来的时候,会继续堆积在缓冲区里面,小心缓冲区溢出哦!
回复
精锐掷矛手 2010-07-09
你将readBuf中的数据memcpy到一个自己定义的数组中,处理自己定义的数组就OK了。每取一块后将数据前移就行了。
回复
fjw666 2010-07-09
[Quote=引用 1 楼 rebort_q 的回复:]
你可以定义一个自己的缓冲区,把读取的数据存到缓冲区中,然后一个一个取。其实就是一个队列。
[/Quote]

现在的问题就是不知道如何一个一个的取啊,以下的程序问题出在哪里
DWORD CCESeries::ReadThreadFunc(LPVOID lparam)
{
CCESeries *ceSeries = (CCESeries*)lparam;

DWORD evtMask;
BYTE * readBuf = NULL;//读取的字节
DWORD actualReadLen=0;//实际读取的字节数
DWORD willReadLen;

DWORD dwReadErrors;
COMSTAT cmState;

// 清空缓冲,并检查串口是否打开。
ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);


//清空串口
PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );

SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
while (TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
if (evtMask & EV_RXCHAR)
{

ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;
if (willReadLen <= 0)
{
continue;
}

readBuf = new BYTE[willReadLen];
ZeroMemory(readBuf,willReadLen);
ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);

//如果读取的数据大于0,
if (actualReadLen>0)
{
//触发读取回调函数
if(ceSeries->m_OnSeriesRead)
{
ceSeries->m_OnSeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
}
}
delete[] readBuf;
readBuf=NULL;
}
}
//如果收到读线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
}
return 0;
}
回复
zxdlms 2010-07-09
将读取的串口数据保存到一个缓存中如CByteArray里面,后面想要哪个数据就取那个数据。
回复
精锐掷矛手 2010-07-09
你可以定义一个自己的缓冲区,把读取的数据存到缓冲区中,然后一个一个取。其实就是一个队列。
回复
发动态
发帖子
硬件/系统
创建于2007-09-28

2590

社区成员

VC/MFC 硬件/系统
申请成为版主
社区公告
暂无公告