主题:串口通讯线程问题

  共有38978人关注过本帖    
帅哥哟,离线,有人找我吗?
bingdongcha
1楼 信息 | 搜索 | 邮箱


加好友 发短信
串口通讯线程问题  发帖心情 Post By:2013-5-21 22:30:00   [只看该作者]

DWORD WINAPI CCESerial::ReceiveThreadFunc(LPVOID lparam)
{
CCESerial *lpSerial = (CCESerial*)lparam;
DWORD     dwEvtMask, dwReadError;
COMSTAT  cmStat;
ULONG     nWillLen;


SetCommMask( lpSerial->m_hSer, EV_RXCHAR|EV_ERR  );
for( ; ; )
{
printf( "WRITE WRITE WRITE WRITE CHAR  \r\n");
/************************************************************************************************
// if( WaitCommEvent( lpSerial->m_hSer, &dwEvtMask, NULL ) )
// {
// SetCommMask( lpSerial->m_hSer, EV_RXCHAR|EV_ERR );
// // get how many data available in receive buffer
// if( dwEvtMask & EV_RXCHAR )
// {
// ClearCommError( lpSerial->m_hSer, &dwReadError, &cmStat ); //取接收数据长度信息
// nWillLen = cmStat.cbInQue;
// if( nWillLen <=0 )
// continue;
//
// lpSerial->m_lDatLen = 0;
// ReadFile( lpSerial->m_hSer, lpSerial->DatBuf, nWillLen, &lpSerial->m_lDatLen, 0 );
//
// if( lpSerial->m_lDatLen>0 )
// {
// // 调用回调函数处理接收到的数据
// lpSerial->OnReceive( );
// }
// }
// else if( dwEvtMask & EV_ERR )
// {
// // 清错误标志
// ClearCommError( lpSerial->m_hSer, &dwReadError, &cmStat );
// lpSerial->OnError( );
// }
//
// }
//
// if( WaitForSingleObject( lpSerial->m_hKillRxThreadEvent, 0 ) == WAIT_OBJECT_0)
// {
// SetEvent( lpSerial->m_hReceiveCloseEvent );
// break;
// }
*************************************************************************************************/
}
return 0;
}


上边这个线程  可以循环打印,但是把注释的部分打开,只能运行一次打印。好像是线程只运行了一次。
在if( WaitCommEvent( lpSerial->m_hSer, &dwEvtMask, NULL ) )设置断点,暂停后也不能单步运行。按单步也直接就启动了。
是和WaitCommEvent( lpSerial->m_hSer, &dwEvtMask, NULL ) 这个函数有关系么??

串口打开时是异步通信方式-非阻塞方式打开的。
m_hComm = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); // 异步通信方式-非阻塞方式

或者有跟好的方法实现在线程内实现收发数据。主要想做循环式通讯规约。

[此贴子已经被作者于2013-5-21 22:39:56编辑过]

  单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
lqk
2楼 信息 | 搜索 | 邮箱


加好友 发短信
  发帖心情 Post By:2013-5-22 9:41:00   [只看该作者]

WINCE不支持重叠I/O模式,所以不能使用FILE_FLAG_VOERLAPPED参数。
WaitCommEvent总是阻塞等待数据接收。
通讯规约一般有固定的格式,需要根据通讯规约将接收数据在本地缓存处理,然后根据接收数据的内核,做相应的应答。

  单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
bingdongcha
3楼 信息 | 搜索 | 邮箱


加好友 发短信
  发帖心情 Post By:2013-5-24 11:27:00   [只看该作者]

现在是这样实现的,把代码贴出来,童鞋们可以借鉴,老鸟们批判下。我继续改正。
电力规约循环发送CDT报文,串口没有用重叠I/O模式,线程启动前先发送一个字节,触发EV_TXEMPTY事件。以后就可以循环发送了,串口有数据来时,也可以接受处理。
最后的一句Sleep();加上它,报文会有卡顿。不加Sleep();这个线程一直在运行,不知道长时间运行对其他线程是否会有影响。暂时测试没有影响,所以把Sleep();封掉了。
DWORD WINAPI CDTSend(PVOID lparam)
{
PVOID lpflag;
lpflag = lparam;



DWORD dwEvtMask, dwReadError;
COMSTAT cmStat;
ULONG nWillLen;
unsigned char buf = 0xff;

BOOL bReadStatus;
cdt_tx0.OpenPort(CDTA_Port,CDTA_Bate,CDTA_Pn,8,1);
SetCommMask(cdt_tx0.m_hComm, EV_RXCHAR|EV_ERR|EV_TXEMPTY);
cdt_tx0.WritePort(&buf,1);
while(TRUE)
{
// 阻塞串口时间 一直等待事件发生。
if(WaitCommEvent(cdt_tx0.m_hComm, &dwEvtMask, NULL))
{
SetCommMask(cdt_tx0.m_hComm, EV_RXCHAR|EV_ERR|EV_TXEMPTY);
if( dwEvtMask & EV_RXCHAR )
{
printf( "CDT_TX0 RECV RECV SUCCESS  \r\n");
ClearCommError( cdt_tx0.m_hComm, &dwReadError, &cmStat ); //取接收数据长度信息
nWillLen = cmStat.cbInQue; // cbInQue:表示接收缓冲区中存储的待ReadFile读取的字节数。
// cbOutQue:表示发送缓冲区中存储的待发送的字节数。
if( nWillLen <=0 )
continue;

cdt_tx0.RecvLen = 0;
bReadStatus = ReadFile(cdt_tx0.m_hComm, cdt_tx0.AcceBuf, nWillLen, &cdt_tx0.RecvLen, NULL);
if(cdt_tx0.RecvLen > 0)
cdt_tx0.Acces(cdt_tx0.AcceBuf,cdt_tx0.RecvLen);
}
if(dwEvtMask & EV_TXEMPTY)
{
cdt_tx0.WritePort(cdt_tx0.SendBuf,cdt_tx0.SendLen);
}
else if(dwEvtMask & EV_ERR)
{
// 清错误标志
ClearCommError(cdt_tx0.m_hComm, &dwReadError, &cmStat);
}

}
// Sleep(99); // 线程挂起时间99MS  调度时间1MS  线程重新运行时间100MS
}
return 0;

}

  单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
lqk
4楼 信息 | 搜索 | 邮箱


加好友 发短信
  发帖心情 Post By:2013-5-24 13:12:00   [只看该作者]

数据的接收和发送完全可以由两个线程来分别完成,在我们网站上有一篇基于RS485的电力系统DL645协议规约的实现方法http://www.emtronix.com/article/article2009326.html,可以做为一个例子参考。
如果需要源码,请留下邮箱。

  单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
bingdongcha
5楼 信息 | 搜索 | 邮箱


加好友 发短信
  发帖心情 Post By:2013-5-24 15:35:00   [只看该作者]

我们也做645规约。
gyangchina@163.com这是我的邮箱,感谢共享源码。
万分感谢!!

  单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
lqk
6楼 信息 | 搜索 | 邮箱


加好友 发短信
  发帖心情 Post By:2013-5-24 17:16:00   [只看该作者]

例程已发到你邮箱,请查收。

  单帖管理 | 引用 | 回复 回到顶部

返回首页

串口通讯线程问题

用户名:
            验证码: 验证码,看不清楚?请点击刷新验证码
内容: