BOOL CCOMReadBuf::GetOneByte(BYTE *cb) { m_Lock.Lock(); if(m_nHead==m_nTail) { m_Lock.Unlock(); return FALSE;//空 } *cb=m_readbuf[m_nTail]; if(m_nTail < m_nBufSize-1) m_nTail++; else m_nTail=0; m_Lock.Unlock(); return TRUE;//空 }
void CCOMReadBuf::Add(BYTE buf[],int nBytes) { int nt,i; m_Lock.Lock(); for(i=0;i BR> { nt=(m_nHead-m_nTail); if(nt<0) nt+=m_nBufSize; if(nt+1==m_nBufSize) break;//緩沖區滿 m_readbuf[m_nHead]=buf[i]; if(m_nHead < m_nBufSize-1) m_nHead++; else m_nHead=0; } m_Lock.Unlock(); } |
(四) 控制命令的發送
控制命令可以從對話條上的編輯框獲取,然后就可以通過寫文件形式從端口發送出去,這部分實現起來較簡單,也牽扯不到線程等技術。主要的代碼主要有:
…… file://從對話條獲取命令行 nRead=m_wndDlgBar.GetDlgItemText(IDC_EDIT_SEND,buf,500); file://向端口發送命令 if(nRead>0) { buf[nRead]=0x0d; buf[nRead+1]=0x00; ::WriteFile(g_hCom,buf,nRead+1,&dwActWrite,NULL); } …… |
(五) 監測信息的顯示
本程序選擇了列表視圖作為數據的顯示途徑。為了能及時的將接收到的數據反饋給監控者,在視類中通過定時器完成定時刷新的功能,可以在視類的OnCreate() 函數里用SetTimer(……)函數在程序開始執行時打開定時器,在OnDestroy()里用KillTimer(……)函數在程序退出前先關閉定時器。在定時器消息 WM_TIMER的響應函數里完成向列表控件添加最新接收到的信息。主要語句有:
…… file://獲取列表視相關的列表空間的句柄 CListCtrl &ListCtrl=GetListCtrl(); file://列表有兩列:收到字符的時間和對應的信息 CTime t = CTime::GetCurrentTime(); CString szTemp; szTemp.Format("%02d:%02d:%02d",t.GetHour(),t.GetMinute(),t.GetSecond()); file://向列表添加信息 int nIndex=ListCtrl.InsertItem(0, szTemp); if(-1!=nIndex) { m_Buf[m_nCurPoint]=0; ListCtrl.SetItemText(nIndex,1,LPTSTR(m_Buf)); } …… |
四、 調試與檢測
現在程序已經寫完,可以編譯運行。我們最好先檢驗一下機器串口是否能正常工作,可用DOS下的Comdebug程序檢查。在確認串口工作正常后,如果條件允許最好同另一臺計算機或外設相連,進行檢測,如筆者用的是一臺高頻段數傳電臺。如果只有一臺計算機也可以進行簡單的測試:將計算機串口的第2腳和第3腳短接,即自己發送、接收數據。如果接有外設,當有采集到的數據送到端口時就會在列表中將時間和信息內容記錄下來,也可以在對話條中輸入命令來控制外設的工作狀態,完全具備實時監控軟件所需的功能。
小結:
串行通訊在通訊領域被廣泛應用,標準的RS-232-C接口已成為計算機、外設、交換機和許多通訊設備的標準接口。計算機與計算機、計算機與外設等都可以通過RS-232-C接口進行方便的連接,以實現監視、控制外設和傳輸數據等目的。對于其他類型的串口通訊程序本文所介紹的方法也是值得借鑒的。本程序由
Microsoft Visual C++ 6.0編譯、在Windows 98下運行通過。