串口VC編程步驟及程序_第1頁
串口VC編程步驟及程序_第2頁
串口VC編程步驟及程序_第3頁
串口VC編程步驟及程序_第4頁
串口VC編程步驟及程序_第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、1添加C+類 CCESeries下面是CCESeries.h 文件的內(nèi)容:#pragma once/定義串口接收數(shù)據(jù)函數(shù)類型/這是一個回調(diào)函數(shù),執(zhí)行該函數(shù)時,表示串口接收到了數(shù)據(jù)。typedef void (CALLBACK* ONSERIESREAD)(void * pOwner /*父對象指針*/,BYTE* buf /*接收到的緩沖區(qū)*/,DWORD dwBufLen /*接收到的緩沖區(qū)長度*/);class CCESeriespublic:CCESeries(void); /CCESeries類的構(gòu)造函數(shù)CCESeries(void); /CCESeries類的析構(gòu)函數(shù)public:/

2、打開串口BOOL OpenPort(void* pOwner,/*指向父指針*/UINT portNo = 1, /*串口號*/UINT baud = 9600, /*波特率*/UINT parity = NOPARITY, /*奇偶校驗*/UINT databits = 8, /*數(shù)據(jù)位*/UINT stopbits = 0 /*停止位*/);/關(guān)閉串口void ClosePort();/同步寫入數(shù)據(jù)BOOL WriteSyncPort(const BYTE*buf , DWORD bufLen);/設(shè)置串口讀取、寫入超時BOOL SetSeriesTimeouts(COMMTIMEOUTS

3、 CommTimeOuts);/得到串口是否打開BOOL GetComOpened();private:/串口讀線程函數(shù),該函數(shù)被定義成私有靜態(tài)。static DWORD WINAPI ReadThreadFunc(LPVOID lparam);private:/關(guān)閉讀線程,當(dāng)使用完串口后,便調(diào)用這個函數(shù)退出串口數(shù)據(jù)接收線程。void CloseReadThread();private:/已打開的串口句柄/ HANDLE m_hComm;/讀線程句柄HANDLE m_hReadThread;/讀線程ID標(biāo)識DWORD m_dwReadThreadID;/讀線程退出事件HANDLE m_hRea

4、dCloseEvent;BOOL m_bOpened; /串口是否打開void * m_pOwner; /指定父對象指針public:ONSERIESREAD m_OnSeriesRead; /串口讀取回調(diào)函數(shù)HANDLE m_hComm;2.下面是CCESeries.cpp文件的內(nèi)容:#include StdAfx.h#include CESeries.h/構(gòu)造函數(shù),將m_hComm初始化為無效的句柄CCESeries:CCESeries()/初始化內(nèi)部變量m_hComm = INVALID_HANDLE_VALUE;m_OnSeriesRead = NULL;m_bOpened = 0;/

5、析構(gòu)函數(shù),檢測如果串口是打開的,則關(guān)閉串口CCESeries:CCESeries()if (m_bOpened)/關(guān)閉串口ClosePort();/串口讀線程函數(shù),該線程用于異步接收串口數(shù)據(jù)。大家應(yīng)仔細(xì)理解該線程的具體實現(xiàn)過程,/該線程通過循環(huán)調(diào)用WaitCommEvent函數(shù)來檢測串口狀態(tài),當(dāng)發(fā)現(xiàn)有數(shù)據(jù)時,調(diào)用/ReadFile函數(shù)讀取數(shù)據(jù),并觸發(fā)回調(diào)函數(shù),由此實現(xiàn)串口數(shù)據(jù)的實時異步讀取。DWORD CCESeries:ReadThreadFunc(LPVOID lparam)CCESeries *ceSeries = (CCESeries*)lparam;DWORD evtMask;BYT

6、E * readBuf = NULL;/讀取的字節(jié)DWORD actualReadLen=0;/實際讀取的字節(jié)數(shù)DWORD willReadLen;DWORD dwReadErrors;COMSTAT cmState;/ 清空緩沖,并檢查串口是否打開。ASSERT(ceSeries-m_hComm !=INVALID_HANDLE_VALUE);/清空串口PurgeComm(ceSeries-m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );SetCommMask (ceSeries-m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );

7、while (TRUE)if (WaitCommEvent(ceSeries-m_hComm,&evtMask,0)SetCommMask (ceSeries-m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );/表示串口收到字符if (evtMask & EV_RXCHAR)ClearCommError(ceSeries-m_hComm,&dwReadErrors,&cmState);willReadLen = cmState.cbInQue ;if (willReadLen m_hComm, readBuf, willReadLen,&actualReadLen,

8、0);/如果讀取的數(shù)據(jù)大于,if (actualReadLen0)/觸發(fā)讀取回調(diào)函數(shù)if (ceSeries-m_OnSeriesRead)ceSeries-m_OnSeriesRead(ceSeries-m_pOwner,readBuf,actualReadLen);/釋放內(nèi)存delete readBuf;readBuf = NULL;/如果收到讀線程退出信號,則退出線程if (WaitForSingleObject(ceSeries-m_hReadCloseEvent,500) =WAIT_OBJECT_0)break;return 0;/關(guān)閉讀線程void CCESeries:Close

9、ReadThread()/設(shè)置讀線程退出信號SetEvent(m_hReadCloseEvent);/設(shè)置所有事件無效無效SetCommMask(m_hComm, 0);/清空所有將要讀的數(shù)據(jù)PurgeComm( m_hComm, PURGE_RXCLEAR );/等待秒,如果讀線程沒有退出,則強(qiáng)制退出if (WaitForSingleObject(m_hReadThread,4000) = WAIT_TIMEOUT)TerminateThread(m_hReadThread,0);m_hReadThread = NULL;/*函數(shù)介紹:打開串口*入口參數(shù):pPortOwner :使用此串口類

10、的窗體句柄portNo :串口號baud :波特率parity :奇偶校驗databits :數(shù)據(jù)位stopbits :停止位*出口參數(shù):(無)*返回值:TRUE:成功打開串口;FALSE:打開串口失敗*/供外部調(diào)用此方法打開串口,該函數(shù)將根據(jù)制定的參數(shù)打開串口,并創(chuàng)建此串口的讀線程,以實現(xiàn)串口數(shù)據(jù)實時異步讀操作。BOOL CCESeries:OpenPort(void * pOwner,UINT portNo , /*串口號*/UINT baud , /*波特率*/UINT parity , /*奇偶校驗*/UINT databits , /*數(shù)據(jù)位*/UINT stopbits /*停止位

11、*/)DCB commParam;TCHAR szPort15;ASSERT(pOwner!=NULL);m_pOwner = pOwner;/ 已經(jīng)打開的話,直接返回if (m_hComm != INVALID_HANDLE_VALUE)return TRUE;/設(shè)置串口名wsprintf(szPort, LCOM%d:, portNo);/打開串口m_hComm = CreateFile(szPort,GENERIC_READ | GENERIC_WRITE, /允許讀和寫0, /獨(dú)占方式(共享模式)NULL,OPEN_EXISTING, /打開而不是創(chuàng)建(創(chuàng)建方式)0,NULL);if

12、(m_hComm = INVALID_HANDLE_VALUE)/ 無效句柄,返回。TRACE(_T(CreateFile 返回?zé)o效句柄n);return FALSE;/ 得到打開串口的當(dāng)前屬性參數(shù),修改后再重新設(shè)置串口。if (!GetCommState(m_hComm,&commParam)/關(guān)閉串口CloseHandle (m_hComm);m_hComm = INVALID_HANDLE_VALUE;return FALSE;/設(shè)置串口參數(shù)commParam.BaudRate = baud; / 設(shè)置波特率commParam.fBinary = TRUE; / 設(shè)置二進(jìn)制模式,此處必須

13、設(shè)置TRUEcommParam.fParity = TRUE; / 支持奇偶校驗commParam.ByteSize = databits; / 數(shù)據(jù)位,范圍:4-8commParam.Parity = parity; / 校驗?zāi)J絚ommParam.StopBits = stopbits; / 停止位commParam.fOutxCtsFlow = FALSE; / No CTS output flow controlcommParam.fOutxDsrFlow = FALSE; / No DSR output flow controlcommParam.fDtrControl = DTR_

14、CONTROL_ENABLE;/ DTR flow control typecommParam.fDsrSensitivity = FALSE; / DSR sensitivitycommParam.fTXContinueOnXoff = TRUE; / XOFF continues TxcommParam.fOutX = FALSE; / No XON/XOFF out flow controlcommParam.fInX = FALSE; / No XON/XOFF in flow controlcommParam.fErrorChar = FALSE; / Disable error r

15、eplacementcommParam.fNull = FALSE; / Disable null strippingcommParam.fRtsControl = RTS_CONTROL_ENABLE;/ RTS flow controlcommParam.fAbortOnError = FALSE; / 當(dāng)串口發(fā)生錯誤,并不終止串口讀寫/設(shè)置串口參數(shù)if (!SetCommState(m_hComm, &commParam)TRACE(_T(SetCommState error);/關(guān)閉串口CloseHandle (m_hComm);m_hComm = INVALID_HANDLE_VAL

16、UE;return FALSE;/設(shè)置串口讀寫時間COMMTIMEOUTS CommTimeOuts;GetCommTimeouts (m_hComm, &CommTimeOuts);CommTimeOuts.ReadIntervalTimeout = MAXDWORD;CommTimeOuts.ReadTotalTimeoutMultiplier = 0;CommTimeOuts.ReadTotalTimeoutConstant = 0;CommTimeOuts.WriteTotalTimeoutMultiplier = 10;CommTimeOuts.WriteTotalTimeoutCo

17、nstant = 1000;if(!SetCommTimeouts( m_hComm, &CommTimeOuts )TRACE( _T(SetCommTimeouts 返回錯誤) );/關(guān)閉串口CloseHandle (m_hComm);m_hComm = INVALID_HANDLE_VALUE;return FALSE;/指定端口監(jiān)測的事件集SetCommMask (m_hComm, EV_RXCHAR);/分配串口設(shè)備緩沖區(qū)SetupComm(m_hComm,512,512);/初始化緩沖區(qū)中的信息PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEA

18、R);CString strEvent;strEvent.Format(LCom_ReadCloseEvent%d,portNo);m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,strEvent);/創(chuàng)建串口讀數(shù)據(jù)監(jiān)聽線程m_hReadThread =CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);TRACE(_T(串口打開成功);m_bOpened = TRUE;return TRUE;/*函數(shù)介紹:關(guān)閉串口*入口參數(shù):(無)*出口參數(shù):(無)*返回值: (無)*/該函

19、數(shù)將退出串口讀線程,并關(guān)閉串口句柄。void CCESeries:ClosePort()/表示串口還沒有打開if (m_hComm = INVALID_HANDLE_VALUE)return ;/關(guān)閉讀線程CloseReadThread();/關(guān)閉串口CloseHandle (m_hComm);/關(guān)閉事件CloseHandle(m_hReadCloseEvent);m_hComm = INVALID_HANDLE_VALUE;m_bOpened = FALSE;/*函數(shù)介紹:往串口寫入數(shù)據(jù)*入口參數(shù):buf :待寫入數(shù)據(jù)緩沖區(qū)bufLen : 待寫入緩沖區(qū)長度*出口參數(shù):(無)*返回值:TRU

20、E:設(shè)置成功;FALSE:設(shè)置失敗*/供外部調(diào)用來向串口發(fā)送數(shù)據(jù)。BOOL CCESeries:WriteSyncPort(const BYTE*buf , DWORD bufLen)DWORD dwNumBytesWritten;DWORD dwHaveNumWritten =0 ; /已經(jīng)寫入多少int iInc = 0; /如果次寫入不成功,返回FALSEASSERT(m_hComm != INVALID_HANDLE_VALUE);doif (WriteFile (m_hComm, /串口句柄buf+dwHaveNumWritten, /被寫數(shù)據(jù)緩沖區(qū)bufLen - dwHaveNu

21、mWritten, /被寫數(shù)據(jù)緩沖區(qū)大小&dwNumBytesWritten, /函數(shù)執(zhí)行成功后,返回實際向串口寫的個數(shù)NULL) /此處必須設(shè)置NULLdwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;/寫入完成if (dwHaveNumWritten = bufLen)break;iInc+;if (iInc = 3)return FALSE;Sleep(10);elsereturn FALSE;while (TRUE);return TRUE;/*函數(shù)介紹:設(shè)置串口讀取、寫入超時*入口參數(shù):CommTimeOuts : 指向C

22、OMMTIMEOUTS結(jié)構(gòu)*出口參數(shù):(無)*返回值:TRUE:設(shè)置成功;FALSE:設(shè)置失敗*/供外部調(diào)用來設(shè)置串口讀取,寫入超時。BOOL CCESeries:SetSeriesTimeouts(COMMTIMEOUTS CommTimeOuts)ASSERT(m_hComm != INVALID_HANDLE_VALUE);return SetCommTimeouts(m_hComm,&CommTimeOuts);/得到串口是否打開BOOL CCESeries:GetComOpened()return m_bOpened;3.添加對話框MFC類:DlgParams接下來為CDlgPara

23、ms 類添加一些變量,用來保存設(shè)置好的串口通訊參數(shù)。找到public:UINT m_portNo; /串口號UINT m_baud; /波特率UINT m_parity; /奇偶校驗UINT m_databits; /數(shù)據(jù)位UINT m_stopbits; /停止位4.串口參數(shù)設(shè)置的對話框上我們添加了5個用來選擇串口通訊參數(shù)的組合框,那么我們在類的源文件中重載OnInitDialog虛函數(shù),在這個函數(shù)中初始化組合框的內(nèi)容。做到這一步,我們先來編譯了一下工程,0 錯誤,兩警告,沒有什么問題,繼續(xù)。在DlgParams.cpp文件中加入如下函數(shù)代碼:BOOL CDlgParams:OnInitDi

24、alog()CDialog:OnInitDialog();/初始化串口參數(shù)下拉框,下拉列表CString strItem = L;CComboBox *pCmbComNo = (CComboBox*)GetDlgItem(IDC_CMB_NUM);CComboBox *pCmbComBaud = (CComboBox*)GetDlgItem(IDC_CMB_BAUD);CComboBox *pCmbComParity = (CComboBox*)GetDlgItem(IDC_CMB_PTY);CComboBox *pCmbComDatabits = (CComboBox*)GetDlgItem

25、(IDC_CMB_DAT);CComboBox *pCmbComStopbits = (CComboBox*)GetDlgItem(IDC_CMB_STOP);/初始化數(shù)據(jù)/串口號pCmbComNo-ResetContent();for (int i=0; i AddString(strItem);pCmbComNo-SetCurSel(0);/ com1:/波特率pCmbComBaud-ResetContent();pCmbComBaud-AddString(L300);pCmbComBaud-AddString(L600);pCmbComBaud-AddString(L1200);pCmb

26、ComBaud-AddString(L2400);pCmbComBaud-AddString(L4800);pCmbComBaud-AddString(L9600);pCmbComBaud-AddString(L19200);pCmbComBaud-AddString(L38400);pCmbComBaud-AddString(L43000);pCmbComBaud-AddString(L56000);pCmbComBaud-AddString(L57600);pCmbComBaud-AddString(L);pCmbComBaud-SetCurSel(5) ; /9600/奇偶校驗pCmbC

27、omParity-ResetContent();pCmbComParity-AddString(LNone);pCmbComParity-AddString(LOdd);pCmbComParity-AddString(LEven);pCmbComParity-SetCurSel(0); / None/數(shù)據(jù)位pCmbComDatabits-ResetContent();pCmbComDatabits-AddString(L8);pCmbComDatabits-AddString(L7);pCmbComDatabits-AddString(L6);pCmbComDatabits-SetCurSel

28、(0); /8/停止位pCmbComStopbits-ResetContent();pCmbComStopbits-AddString(L1);pCmbComStopbits-AddString(L1.5);pCmbComStopbits-AddString(L2);pCmbComStopbits-SetCurSel(0); /1return TRUE;6.保存,編譯。程序出錯了。錯誤類型如下:error C2509: OnInitDialog : member function not declared in CDlgParams這個函數(shù)我們沒有去聲明。在Dlgparams.h 文件中聲明該

29、函數(shù),如下圖所示:重新編譯,錯誤沒有了。7.接下來完成“連接”按鈕的單擊響應(yīng)函數(shù)。雙擊“連接”按鈕,添加代碼如下:void CDlgParams:OnBnClickedOk()/ TODO: 在此添加控件通知處理程序代碼/單擊按鈕事件CString strTmp;CComboBox *pCmbComNo = (CComboBox*)GetDlgItem(IDC_CMB_NUM);CComboBox *pCmbComBaud = (CComboBox*)GetDlgItem(IDC_CMB_BAUD);CComboBox *pCmbComParity = (CComboBox*)GetDlgIt

30、em(IDC_CMB_PTY);CComboBox *pCmbComDatabits = (CComboBox*)GetDlgItem(IDC_CMB_DAT);CComboBox *pCmbComStopbits = (CComboBox*)GetDlgItem(IDC_CMB_STOP);pCmbComBaud-GetWindowTextW(strTmp);m_portNo = pCmbComNo-GetCurSel() + 1; /串口號m_baud = _wtoi(strTmp); /波特率m_parity = pCmbComParity-GetCurSel(); /奇偶校驗pCmbC

31、omDatabits-GetWindowTextW(strTmp);m_databits = _wtoi(strTmp); /數(shù)據(jù)位m_stopbits = pCmbComStopbits-GetCurSel(); /停止位/關(guān)閉對話框OnOK();8.到了這,CDlgParams 類的操作就基本完成了。接下來為CBomcTestDlg 類添加一個CCESeries對象指針。public:/ 串口對象指針CCESeries *m_pSerial;然后在BomcTestDlg類的頭文件中添加CCESeries類的頭文件引用,如下:#include CESeries.h9.接下來完成“連接串口設(shè)備

32、”按鈕單擊響應(yīng)函數(shù),如下:void CBomcTestDlg:OnBnClickedBtnConn()/判斷串口是否已經(jīng)打開if (m_pSerial != NULL)m_pSerial-ClosePort();delete m_pSerial;m_pSerial = NULL;/串口參數(shù)輸入對話框CDlgParams dlgParams;if (dlgParams.DoModal() = IDOK)/新建串口通訊對象m_pSerial = new CCESeries();/打開串口if (m_pSerial-OpenPort(this,dlgParams.m_portNo,dlgParams.m_baud,dlgParams.m_parity,dlgParams.m_databits,dlgParams.m_stopbits)AfxMessageBox(L串口連接成功);else

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論