最近在整理文件的時候發現了原先寫的一個串口程序,為了提高重用性就又重新的寫了一下。根據以前的使用過的一系列串口操作軟件發現,大多數的串口操作軟件不具備自動的記錄保存功能,於是我就在這裡把它加進去,記錄文件是在應用程序目錄下 以時間命名的文本文件。現在發布的這個程序還有一些功能沒有實現不過這不影響使用。如果有需要大家可以自行添加代碼。下面我主要說明一下程序的核心類CSuperSerialPort。該類主要功能有:
控制串口收發數據並利用window系統的消息來轉發接收到的數據;
支持一個CSuperSerialPort對象向多個窗口發送數據;
支持發送大塊數據;
支持動態設置收發緩存區大小;
支持利用外部線程進行文件傳輸;
支持收發數據統計;
支持自定義錯誤信息;
該類還有兩個輔助的結構體 WIN_ARG 和 tagPackage。WIN_ARG 是窗體描述結構體,該結構體包含了窗體指針、自定義消息和位置ID。
typedef struct WIN_ARG
{
UINT winId;
CWnd* pWin;
DWORD msg;
}WINARG, *pWINARG;
tagPackage 是數據包描述結構體,該結構體包含了數據長度、數據類別和數據值。CSuperSerialPort利用這個結構體來分解大塊數據然後發送。
typedef struct tagPackage
{
enum emMaxSize
{ emMAX_SIZE = 1024 };
UINT iLen;
UINT iType;
BYTE pData[emMAX_SIZE];
}PACKAGE, * pPACKAGE;
在串口程序的開發過程中,最麻煩的問題就是需要事先確定緩存區的大小。如果傳輸時按協議傳輸這個一般沒什麼問題,但是如果按一個字節一個字節的進行傳輸,那麼在收數據的時候就很麻煩。解決這一問題時我利用了串口中cbInQue這一屬性,同時為了提高程序的性能啟用了一個接收線程,並將收下來的數據都發往指定的窗體對象然後再進行處理。如:
pPACKAGE pPack = new PACKAGE;
為了協同串口的收發,在初始化串口的時候要啟用FILE_FLAG_OVERLAPPED這一屬性,如
DWORD rdLen = pCom->m_comState.cbInQue;
pPack->iLen = rdLen;
CreateFile(m_com.com, GENERIC_READ | GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
當然在接收的線程中還加入了互斥對象和臨界區用於控制線程和數據統計。如果你直接使用CSuperSerialPort類,程序已經替你完成了這些任務。如:
m_pSSP->Open(m_comName, m_uComRate, m_uComParity, m_uComDataBits, m_fComStopBits);
詳細情況可以參照TestSerialPort2Dlg.cpp中的代碼。
m_pSSP->StartReceive(m_pSSP)
為了解決一個串口實例向多個窗口顯示數據問題,我在CSuperSerialPort類中添加了一個窗體向量表typedef vector vWINLIST;你可以通過Attach和Detach函數來控制窗體數量。如果需要添加其他的功能到CSuperSerialPort類中,有三種方法可以實現:
直接修改CSuperSerialPort類代碼;
繼承CSuperSerialPort類;
調用GetComHandle返回串口句柄;
具體的細節請看代碼文件我已經做了大量的注釋,源代碼的 AT 文件夾下是 Modem 命令集文件,在Modem檢測功能中使用。該程序有兩個可以重用的類文件,串口通訊類文件superSP.cpp, superSP.h;文件操作類文件fileCtrl.cpp, fileCtrl.h。
如果還有問題可以發郵件給我[email protected]。由於水平有限有錯誤的地方歡迎指正,最後祝大家工作、學習順利。
本文配套源碼