用API编程,仿照龚建伟的串口助手,用的是SERIALPORT.CPP,SERIALPORT.H.在第一个对话框打开串口,联机都没问题。
在第二个中,发送没问题,接收不到。代码如下:ON_MESSAGE(WM_COMM_RXCHAR, OnComm)LONG CComDetectDlg::OnComm(WPARAM ch, LPARAM port)
{

_TCHAR *szmsg[]={_T("通信尚未连接"), _T("通信状态良好"), _T("通信未能建立连接") };
if(port==1)     //COM1接收到数据
{ CString str;
unsigned char i=0;
unsigned char abcd[512];

str.Format(_T("%02X "),ch); m_strEditReceiveMsg += str;
int len=m_SerialPort[0].Str2Hex(m_strEditReceiveMsg,abcd);
rxdatacount++;   //接收的字节计数
CString strTemp;
strTemp.Format(_T("%ld"),rxdatacount);
strTemp="RX:"+strTemp;
m_ctrlRXCOUNT.SetWindowText(strTemp);  //显示接收计数

///FF 01 53 00 2E E0 22 FE
if(abcd[2] == 0x41 )
{

switch(abcd[3])
{
case 0x99:
{
//GetDlgItem(IDC_BTN_COMM1_START1)->EnableWindow(true);
// m_strAlarmComm1="应答成功";
SetDlgItemText(IDC_EDIT1, szmsg[ 1] );
ConnectOKFlag1=TRUE;
m_SerialPort[0].m_bConnectOKFlag=TRUE;
//g_pTciComm1->m_bConnectOKFlag[0]=TRUE;///?????????????????????????
for(i=0;i<12;i++)
abcd[i]=0;
i=0;
// m_strEditReceiveMsg.Empty();
str.Empty();
UpdateData(FALSE); 
}
break;
case 0x00:
{
}
break;
case 0x01:
{
// m_strAlarmComm1="运行成功";
for(i=0;i<12;i++)
abcd[i]=0;
i=0;
// m_strEditReceiveMsg.Empty();
str.Empty();
UpdateData(FALSE); 
}
break;
case 0x02:
{
// m_strAlarmComm1="停止成功";
}
break;
case 0x03:
{
// m_strAlarmComm1="快注成功";
}
break;
case 0x04:
{
// m_strAlarmComm1="静音成功";
}
break;
case 0x05:
{
}
break;
case 0x06:
{
}
break;
}
}
else if(abcd[2]==0x57)
{
//GetDlgItem(IDC_BTN_COMM1_START1)->EnableWindow(false);
// m_strAlarmComm1="报警停止"; }// m_strEditReceiveMsg.Empty();
str.Empty();
UpdateData(FALSE); 
}
else if(port==4)     //COM1接收到数据
{
CString str2;
unsigned char i=0;
unsigned char abcd2[512]; str2.Format(_T("%02X "),ch); m_strEditReceiveMsg2 += str2;
int len=m_SerialPort[1].Str2Hex(m_strEditReceiveMsg2,abcd2); rxdatacount++;   //接收的字节计数
CString strTemp;
strTemp.Format(_T("%ld"),rxdatacount);
strTemp="RX:"+strTemp;
m_ctrlRXCOUNT.SetWindowText(strTemp);  //显示接收计数 if(abcd2[2] == 0x41 )
{

switch(abcd2[3])
{
case 0x99:
{
//GetDlgItem(IDC_BTN_COMM1_START2)->EnableWindow(true);
// m_strAlarmComm2="应答成功";
SetDlgItemText(IDC_EDIT2, szmsg[ 1] );
ConnectOKFlag2=TRUE;
m_SerialPort[1].m_bConnectOKFlag=TRUE; // g_pTciComm1->m_bConnectOKFlag[1]=TRUE;/////?????????????????????????
for(i=0;i<12;i++)
abcd2[i]=0;
i=0;
// m_strEditReceiveMsg2.Empty();
str2.Empty();
UpdateData(FALSE); 
}
break;
case 0x00:
{
}
break;
case 0x01:
{
// m_strAlarmComm2="运行成功";
for(i=0;i<12;i++)
abcd2[i]=0;
i=0;
// m_strEditReceiveMsg2.Empty();
str2.Empty();
UpdateData(FALSE); 
}
break;
case 0x02:
{
// m_strAlarmComm2="停止成功";
}
break;
case 0x03:
{
// m_strAlarmComm2="快注成功";
}
break;
case 0x04:
{
// m_strAlarmComm2="静音成功";
}
break;
case 0x05:
{
}
break;
case 0x06:
{
}
break;
}
}
else if(abcd2[2]==0x57)
{
//GetDlgItem(IDC_BTN_COMM1_START2)->EnableWindow(false);
// m_strAlarmComm2="报警停止"; //UpdateData(FALSE);
//m_strEditReceiveMsg2.Empty();
} i=0;
// m_strEditReceiveMsg2.Empty();
str2.Empty();
UpdateData(FALSE);  //将接收到的字符显示在接收编辑框中
}
else if(port==6)     //COM1接收到数据
{
CString str3;
unsigned char i=0;
unsigned char abcd3[512]; str3.Format(_T("%02X "),ch); m_strEditReceiveMsg3 += str3;
int len=m_SerialPort[2].Str2Hex(m_strEditReceiveMsg3,abcd3); rxdatacount++;   //接收的字节计数
CString strTemp;
strTemp.Format(_T("%ld"),rxdatacount);
strTemp="RX:"+strTemp;
m_ctrlRXCOUNT.SetWindowText(strTemp);  //显示接收计数

if(abcd3[2] == 0x41 )
{

switch(abcd3[3])
{
case 0x99:
{
//GetDlgItem(IDC_BTN_COMM1_START3)->EnableWindow(true);
// m_strAlarmComm3="应答成功";
SetDlgItemText(IDC_EDIT3, szmsg[ 1] );
ConnectOKFlag3=TRUE;
m_SerialPort[2].m_bConnectOKFlag=TRUE;
// g_pTciComm1->m_bConnectOKFlag[2]=TRUE;///?????????????????????????
for(i=0;i<12;i++)
abcd3[i]=0;
i=0;
// m_strEditReceiveMsg3.Empty();
str3.Empty();
UpdateData(FALSE); 
}
break;
case 0x00:
{
}
break;
case 0x01:
{
// m_strAlarmComm3="运行成功";
for(i=0;i<12;i++)
abcd3[i]=0;
i=0;
// m_strEditReceiveMsg3.Empty();
str3.Empty();
UpdateData(FALSE); 
}
break;
case 0x02:
{
// m_strAlarmComm3="停止成功";
}
break;
case 0x03:
{
// m_strAlarmComm3="快注成功";
}
break;
case 0x04:
{
// m_strAlarmComm3="静音成功";
}
break;
case 0x05:
{
}
break;
case 0x06:
{
}
break;
}
}
else if(abcd3[2]==0x57)
{
////GetDlgItem(IDC_BTN_COMM1_START3)->EnableWindow(false);
// m_strAlarmComm3="报警停止"; //UpdateData(FALSE);
//m_strEditReceiveMsg3.Empty();
} i=0;
// m_strEditReceiveMsg3.Empty();
str3.Empty();
UpdateData(FALSE); 
}
return 0;
}

解决方案 »

  1.   

    SERIALPORT.CPP中已经包含了线程。在第二个对话框中,直接发送。没有重新打开串口。如果在每个对话框都打开关闭串口,是不是也太麻烦了?在对话框中用消息ON_MESSAGE(WM_COMM_RXCHAR, OnComm)
      

  2.   

    三个串口。硬件没问题。在第一个开机进入的对话框串口的一切操作都没问题。
    线程。SDI项目工程CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
    IDR_MAINFRAME,
    RUNTIME_CLASS(CTciDoc),
    RUNTIME_CLASS(CMainFrame),       // main SDI frame window
    //RUNTIME_CLASS(CTciOverView));
    RUNTIME_CLASS(CTciView));
    AddDocTemplate(pDocTemplate);
    ////////////////////////////////////////////////////////////////////
    UINT CRunMain::TciRun_Thread(LPVOID lParam)
    {
    ASSERT( this == lParam ); int wrr = false;
    int runOk = false; m_Timer.SetTimerInterval( g_nTS_Now*1000 );
    m_Timer.StartSampleTimer_MM(); HANDLE myhandle[] = { m_hEventAppExit, m_Timer.GetHandle() }; g_pRunTci->BeginRun();
    PostMessage(m_hWndMain, WM_RUN_NEW_SAMPLE_COME, e_TciRun, e_runInit);
    for(;;)
    {
    wrr = ::WaitForMultipleObjects(_countof(myhandle), myhandle, false, g_c_nWaitEvent) ; 
    if( wrr == WAIT_OBJECT_0 )
    break; // 结束线程

    else if( wrr == WAIT_OBJECT_0 +1 )
    {
    runOk = g_pRunTci->RunOnce();


    if( runOk & 0x07 )
    {
    PostMessage(m_hWndMain, WM_RUN_NEW_SAMPLE_COME, e_TciRun, runOk);

    // }
    // if( runOk & 0x0700)
    // {
    //  ::SetEvent(m_hEventDataToSendReady);///  }
    }
    else if( wrr == WAIT_TIMEOUT )
    {
    }
    else if( wrr == WAIT_FAILED )
    {
    ASSERT(0);
    }
    }
    g_pRunTci->FinishRun();
    PostMessage(m_hWndMain, WM_RUN_NEW_SAMPLE_COME, e_TciRun, e_runFinish);
    m_pThread_TciRun = NULL;
    TRACE(_T("TciRun_Thread Exit.\n"));
    return 0;
    }
      

  3.   

    //创建线程
    BOOL CRunMain::Start_Service()
    {
    m_hWndMain = AfxGetMainWnd()->GetSafeHwnd();//取得句柄 if( ! m_hEventAppExit )//建立事件
    m_hEventAppExit = ::CreateEvent(NULL, TRUE, false, _T("TciRunExit") );
    ASSERT( m_hEventAppExit );
    if( ! m_hEventDataToSendReady )
    m_hEventDataToSendReady = ::CreateEvent(NULL, TRUE, false, _T("DataReady") );
    ASSERT( m_hEventDataToSendReady ); m_pThread_TciRun = AfxBeginThread(_TciRun_Thread, this, THREAD_PRIORITY_NORMAL); // THREAD_PRIORITY_TIME_CRITICAL);
    m_pThread_TciRun->m_bAutoDelete = true;
    g_LogThreadResult(m_pThread_TciRun, _T("CRunMain::Start() : 创建TciRun线程:") );
    return true;
    }UINT CRunMain::_TciRun_Thread(LPVOID lParam)
    {
    CRunMain* pRunMain = static_cast<CRunMain*>(lParam);
    return pRunMain->TciRun_Thread(lParam);
    }
      

  4.   

    多个对话框,多线程,如何操作串口呢?其中第二第三个对话框要经常切换。
    void CMainFrame::DoSwitchView(int nView)
    {
    CView* pOldActiveView = GetActiveView();
    CView* pNewActiveView = (CView*) GetDlgItem(nView+10);

    if (pNewActiveView == NULL) 
    {
    switch (nView) 
    {
    case e_TciView:
    // pNewActiveView = (CView*) new CTciView;
    pNewActiveView = (CView*) RUNTIME_CLASS(CTciView)->CreateObject();
    break;
    case e_TciOverView:
    //pNewActiveView = (CView*) new CTciOverView;
    pNewActiveView = (CView*) RUNTIME_CLASS(CTciOverView)->CreateObject();
    break;
    } CCreateContext context;
    context.m_pCurrentDoc = pOldActiveView->GetDocument();
    pNewActiveView->Create(NULL, NULL, WS_CHILD|WS_BORDER,
    CFrameWnd::rectDefault, this, nView, &context);
    pNewActiveView->OnInitialUpdate();
    } SetActiveView(pNewActiveView);
    pNewActiveView->ShowWindow(SW_SHOW);

    pOldActiveView->ShowWindow(SW_HIDE);
    pOldActiveView->SetDlgCtrlID( 10+(
    pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CTciView) ? 
    e_TciView : e_TciOverView) );

    pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);

    RecalcLayout();
    }void CMainFrame::OnViewOverChannel(int uID) 
    {
    // TODO: Add your command handler code here CView* pv = GetActiveView();
    int br = pv->IsKindOf( RUNTIME_CLASS(CTciOverView) );
    int eView = br ? e_TciView: e_TciOverView;
    DoSwitchView(eView);
    }void CMainFrame::OnUpdateViewOverChannel(CCmdUI* pCmdUI) 
    {
    // TODO: Add your command update UI handler code here

    int idCurr = pCmdUI->m_nID - ID_VIEW_OVERVIEW;
    CView* pv = GetActiveView();
    int br = pv->IsKindOf( RUNTIME_CLASS(CTciOverView) ); pCmdUI->Enable( br == idCurr);
    // pCmdUI->SetCheck( br == idCurr);
    pCmdUI->SetRadio( br != idCurr);

    }
      

  5.   

    ding ......
    帮忙给点建议,如何在多界面进行串口通讯呢?