关于一个串口读写数据的有关问题

请教各位关于一个串口读写数据的问题?
本帖最后由 VisualEleven 于 2014-08-15 18:11:01 编辑
各位中午好。
最近在写短信猫发短信时碰到一点问题,在此跟各位讨论一番。
首先是关于串口读写的问题。

这是我在主程序中对writeComm、readComm的调用。

if( 0 == writeComm( text.c_str(), text.length() ) )
return WRITE_ERROR;

char receiveChar[512] = {0};
if( 0 == readComm(receiveChar) )
return READ_ERROR;

下面贴出writeComm、readComm 2个函数的实现。

DWORD SMSNew::writeComm( const char *buf,DWORD dwLength )
{
if ( NULL == buf || 0 == buf[0] )
return 0;

DWORD length = dwLength;
COMSTAT comStat;
DWORD dwErrorFlags;

ClearCommError(_hCom,&dwErrorFlags,&comStat);
PurgeComm(_hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
BOOL fState = WriteFile(_hCom,buf,length,&length,&_osWrite);

if( !fState )
{

if( ERROR_IO_PENDING == GetLastError() )
{
GetOverlappedResult(_hCom,&_osWrite,&length,TRUE);// 等待
}
else
length = 0;
}

return length;
}

DWORD SMSNew::readComm( char* receiveData )
{
COMSTAT ComStat;
DWORD dwErrorFlags;

ClearCommError(_hCom, &dwErrorFlags, &ComStat);
DWORD length = 0;
if( ReadFile(_hCom, receiveData, ComStat.cbInQue, &length, &_osRead) )
{
receiveData[length] = '\0';
return length;
}
else 
return 0;

}


问题在于:
1、每次我调试运行的时候,分别设了2个断点,一个断点在writeComm的return处,一个断点在readComm的return处,那么,readComm是能完全读到期望的内容的,但是一旦我只设一个断点在readComm的return处,ReadFile的时候发现串口缓冲区的长度为0,也就是ComStat.cbInQue为0.
2、如果我在主函数调用中等writeComm return之后加上一句sleep语句,即使我只设一个断点在readComm的return处,也是同样能读到预期数据,也就是ComStat.cbInQue不为0.

所以我就想,是不是写数据到串口,到串口将写入的数据放到缓冲区不是一个原子行为。而是拆分开的,中间有时延,请教各位。这样对吗?
------解决方案--------------------
LZ是把串口23脚短路在本机上测试吧,从发送到接收确实要一定的时间,我用的是mscomm控件,有一个事件表示收到了数据。这种文件读写的方式,应该也有类似的机制吧?
------解决方案--------------------
楼主两个问题的原因都是对串口发送和接收数据的流程不熟悉所形成的。数据从缓冲区到串口硬件需调制成0、1的高低脉冲才能发送。这样就可以理解串口发送任何一帧数据都是需要时间的。

一般利用波特率和数据总量估算发送一个数据帧所需的时长,所以在调试串口时,需要在发送后加入时延