一个关于多线程串行通讯的问题!! 遇到一个难题,请教高手指导一二。就是用多线程开发一个串行通讯程序。主要就是从串口收发数据,不知道是不是应该使用异步方式、还是同步方式,使用查询方式,还是用自动信号方式或自动中断方式处理数据。希望高手提示一下流程,要用到那些知识,要是能详细的说明开发流程,本人感激不尽!!!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 如果是一问一答(命令方式)方式,用同步就可以了。writefile()完之后readfile()就可以了 是,我忘了你要同时操作多路串口了,给你一个我程序的一部分吧,是一个线成的代码,包括了异步打开串口等。打开操作已经被封装,但是流程比较清晰DWORD WINAPI ThreadCommProc( LPVOID lpParameter){ CDeviceDlg *pParentWnd; BYTE gtitem[]={0x01},buscode[9],buf[300]; char CommPort[20]={"\\\\.\\"},mp[50]; int redo,status,ret,iwait,iGTdivice, retvalue; unsigned short elapsed_time; struct _timeb start, finish; double timediff; // 8-7 CRecord m_record; pParentWnd=(CDeviceDlg *) lpParameter; //打开串口 strcpy(CommPort,"\\\\.\\"); strcat(CommPort,pParentWnd->CommPort); if (pParentWnd->m_comm.open(CommPort,115200,1)!=1){ SetEvent(pParentWnd->ExitedEvent); AfxMessageBox("不能打开串口",MB_OK); return 0; } //设置字符事件 pParentWnd->m_comm.SetEventChar(0x02); //清串口 pParentWnd->m_comm.PurgeIn(); status=0; iwait=0; iGTdivice = 0; while(WaitForSingleObject(pParentWnd->ExitEvent,0)==WAIT_TIMEOUT) { // 屏蔽在与采集盒通讯前与采集器的握手 // 2002-2-1/* if (status==0) { if (!initdevice(pParentWnd)) { if (iwait==0) { pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 等待与采集器通讯..."); } continue; } pParentWnd->PostMessage(WM_APP_SIGNAL,1,2); status=1; iwait=1; }*/ //置RTS-发送请求线为低 memset(buf, 0, 300); // 清缓冲区 2002-7-22 pParentWnd->m_comm.SetRTS(0); pParentWnd->PostMessage(WM_APP_SIGNAL,1,0); if (iwait == 0) { pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 等待与采集盒通讯...(请检查采集盒是否上电或串口是否连接)"); iwait = 1; } if (!ReceiveHandshake(pParentWnd)) continue; _ftime( &start); pParentWnd->m_time.SetWindowText(""); pParentWnd->PostMessage(WM_APP_ERRORMSG,0,0); //点采集器灯 // 2002-2-1 if (iGTdivice == 0) { pParentWnd->PostMessage(WM_APP_SIGNAL,1,2); iGTdivice = 1; } //点采集灯 pParentWnd->PostMessage(WM_APP_SIGNAL,2,2); //发启动采集命令 redo=0; /*----------通讯问题主要发生在发送启动采集命令和接收应答---------*/ SendStartGTCmd(pParentWnd,1,gtitem); Sleep(5); do{ ret=ReceiveGTStatusInfo(buf,pParentWnd); if (ret==2) break; if (ret==0) SendSynHead(pParentWnd); // 判断采集盒是否为空 2002-7-19 if (ret==-1) { SendNak(pParentWnd); break; } }while ((ret!=1)&&(redo++<3)); /*----------- 2002-7-22------------*/ if (ret!=1) { //灭采集灯 pParentWnd->PostMessage(WM_APP_SIGNAL,2,1); if (ret==2) { pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集盒内没有文件!"); continue; } else { pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 与采集盒通讯发生错误,请拔出采集盒重试!"); continue; } } if (buf[2]!=0x01) { //灭采集灯 pParentWnd->PostMessage(WM_APP_SIGNAL,2,1); pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集盒状态不正确,不能采集数据"); continue; } SendAck(pParentWnd); // 2002-7-17 //pParentWnd->PostMessage(WM_APP_ITEMNUM,(WPARAM)buf[3],0); //接收数据 memset(buscode,0,9); retvalue = ReceiveGtData(buscode,pParentWnd); if (retvalue == 1) { _ftime( &finish); if (finish.millitm>=start.millitm) { timediff=difftime(finish.time,start.time); elapsed_time=finish.millitm-start.millitm; } else { timediff=difftime(finish.time-1,start.time); elapsed_time=finish.millitm-start.millitm+1000; } sprintf(mp,"%6.0f.%d秒",timediff,elapsed_time); pParentWnd->m_time.SetWindowText(mp); pParentWnd->PostMessage(WM_APP_ERRORMSG,0,NULL); } else { if (retvalue == 10) { pParentWnd->PostMessage(WM_APP_SIGNAL,2,1); pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集盒内数据不完整!"); continue; } else { pParentWnd->PostMessage(WM_APP_SIGNAL,2,1); pParentWnd->PostMessage(WM_APP_SETPRGPOS,0,0); pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集时发生错误,请重采!"); // 8-7 m_record.DeleteErrFile(); continue; } } //灭采集灯 pParentWnd->PostMessage(WM_APP_SIGNAL,2,1); pParentWnd->PostMessage(WM_APP_SETPRGPOS,0,0); pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 数据成功采集!"); } pParentWnd->m_comm.Purge(); pParentWnd->m_comm.Close(); SetEvent(pParentWnd->ExitedEvent); return 0;} 使用treeview如何获得选中节点的信息 创建 DLL 是如何使用系统时间函数? 为什么我执行可以但是一调试就报错 有鼠标“变形”事件吗? 看书遇到了问题,请教老师们:) this is right or ....thanks! 给几个不用MFC的理由? 请问 :如何配置宽带 如何向RichEdit中读入写字板或记事本文件的内容。 函数也择窝? 怎样设置一组RADIO无效?????------在线等待 CToolTipCtrl如何能够在CComboBox控件上显示提示信息呢???
DWORD WINAPI ThreadCommProc( LPVOID lpParameter)
{
CDeviceDlg *pParentWnd;
BYTE gtitem[]={0x01},buscode[9],buf[300];
char CommPort[20]={"\\\\.\\"},mp[50];
int redo,status,ret,iwait,iGTdivice, retvalue;
unsigned short elapsed_time;
struct _timeb start, finish;
double timediff;
// 8-7
CRecord m_record;
pParentWnd=(CDeviceDlg *) lpParameter;
//打开串口
strcpy(CommPort,"\\\\.\\");
strcat(CommPort,pParentWnd->CommPort);
if (pParentWnd->m_comm.open(CommPort,115200,1)!=1){
SetEvent(pParentWnd->ExitedEvent);
AfxMessageBox("不能打开串口",MB_OK);
return 0;
}
//设置字符事件
pParentWnd->m_comm.SetEventChar(0x02);
//清串口
pParentWnd->m_comm.PurgeIn();
status=0;
iwait=0;
iGTdivice = 0;
while(WaitForSingleObject(pParentWnd->ExitEvent,0)==WAIT_TIMEOUT)
{
// 屏蔽在与采集盒通讯前与采集器的握手 // 2002-2-1
/*
if (status==0)
{
if (!initdevice(pParentWnd)) {
if (iwait==0) {
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 等待与采集器通讯...");
}
continue;
}
pParentWnd->PostMessage(WM_APP_SIGNAL,1,2);
status=1;
iwait=1;
}
*/
//置RTS-发送请求线为低
memset(buf, 0, 300); // 清缓冲区 2002-7-22 pParentWnd->m_comm.SetRTS(0);
pParentWnd->PostMessage(WM_APP_SIGNAL,1,0);
if (iwait == 0)
{
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 等待与采集盒通讯...(请检查采集盒是否上电或串口是否连接)");
iwait = 1;
}
if (!ReceiveHandshake(pParentWnd)) continue;
_ftime( &start);
pParentWnd->m_time.SetWindowText("");
pParentWnd->PostMessage(WM_APP_ERRORMSG,0,0);
//点采集器灯 // 2002-2-1
if (iGTdivice == 0)
{
pParentWnd->PostMessage(WM_APP_SIGNAL,1,2);
iGTdivice = 1;
}
//点采集灯
pParentWnd->PostMessage(WM_APP_SIGNAL,2,2);
//发启动采集命令
redo=0;
/*----------通讯问题主要发生在发送启动采集命令和接收应答---------*/
SendStartGTCmd(pParentWnd,1,gtitem);
Sleep(5);
do{
ret=ReceiveGTStatusInfo(buf,pParentWnd);
if (ret==2)
break;
if (ret==0)
SendSynHead(pParentWnd);
// 判断采集盒是否为空 2002-7-19 if (ret==-1) {
SendNak(pParentWnd);
break;
}
}while ((ret!=1)&&(redo++<3));
/*----------- 2002-7-22------------*/ if (ret!=1) {
//灭采集灯
pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
if (ret==2) {
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集盒内没有文件!");
continue;
} else {
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 与采集盒通讯发生错误,请拔出采集盒重试!");
continue;
}
} if (buf[2]!=0x01) {
//灭采集灯
pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集盒状态不正确,不能采集数据");
continue;
} SendAck(pParentWnd); // 2002-7-17
//pParentWnd->PostMessage(WM_APP_ITEMNUM,(WPARAM)buf[3],0);
//接收数据
memset(buscode,0,9);
retvalue = ReceiveGtData(buscode,pParentWnd);
if (retvalue == 1)
{
_ftime( &finish);
if (finish.millitm>=start.millitm)
{
timediff=difftime(finish.time,start.time);
elapsed_time=finish.millitm-start.millitm;
}
else
{
timediff=difftime(finish.time-1,start.time);
elapsed_time=finish.millitm-start.millitm+1000;
}
sprintf(mp,"%6.0f.%d秒",timediff,elapsed_time);
pParentWnd->m_time.SetWindowText(mp);
pParentWnd->PostMessage(WM_APP_ERRORMSG,0,NULL);
}
else
{
if (retvalue == 10)
{
pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集盒内数据不完整!");
continue;
}
else
{
pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
pParentWnd->PostMessage(WM_APP_SETPRGPOS,0,0);
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 采集时发生错误,请重采!");
// 8-7
m_record.DeleteErrFile();
continue;
}
}
//灭采集灯
pParentWnd->PostMessage(WM_APP_SIGNAL,2,1);
pParentWnd->PostMessage(WM_APP_SETPRGPOS,0,0);
pParentWnd->PostMessage(WM_APP_ERRORMSG,1,(LPARAM)" 数据成功采集!");
} pParentWnd->m_comm.Purge();
pParentWnd->m_comm.Close();
SetEvent(pParentWnd->ExitedEvent); return 0;
}