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

下載本文檔

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

文檔簡(jiǎn)介

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

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

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

4、dCloseEvent;BOOL m_bOpened; /串口是否打開(kāi)void * m_pOwner; /指定父對(duì)象指針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初始化為無(wú)效的句柄CCESeries:CCESeries()/初始化內(nèi)部變量m_hComm = INVALID_HANDLE_VALUE;m_OnSeriesRea

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

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

7、Comm, EV_RXCHAR | EV_CTS | EV_DSR );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.cbInQu

8、e ;if (willReadLen <= 0)continue;/分配內(nèi)存readBuf = new BYTEwillReadLen;ZeroMemory(readBuf,willReadLen);/讀取串口數(shù)據(jù)ReadFile(ceSeries->m_hComm, readBuf, willReadLen,&actualReadLen,0);/如果讀取的數(shù)據(jù)大于,if (actualReadLen>0)/觸發(fā)讀取回調(diào)函數(shù)if (ceSeries->m_OnSeriesRead)ceSeries->m_OnSeriesRead(ceSeries->

9、m_pOwner,readBuf,actualReadLen);/釋放內(nèi)存delete readBuf;readBuf = NULL;/如果收到讀線(xiàn)程退出信號(hào),則退出線(xiàn)程if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) =WAIT_OBJECT_0)break;return 0;/關(guān)閉讀線(xiàn)程void CCESeries:CloseReadThread()/設(shè)置讀線(xiàn)程退出信號(hào)SetEvent(m_hReadCloseEvent);/設(shè)置所有事件無(wú)效無(wú)效SetCommMask(m_hComm, 0);/清空所有將要讀的數(shù)據(jù)Pur

10、geComm( m_hComm, PURGE_RXCLEAR );/等待秒,如果讀線(xiàn)程沒(méi)有退出,則強(qiáng)制退出if (WaitForSingleObject(m_hReadThread,4000) = WAIT_TIMEOUT)TerminateThread(m_hReadThread,0);m_hReadThread = NULL;/*函數(shù)介紹:打開(kāi)串口*入口參數(shù):pPortOwner :使用此串口類(lèi)的窗體句柄portNo :串口號(hào)baud :波特率parity :奇偶校驗(yàn)databits :數(shù)據(jù)位stopbits :停止位*出口參數(shù):(無(wú))*返回值:TRUE:成功打開(kāi)串口;FALSE:打開(kāi)串口

11、失敗*/供外部調(diào)用此方法打開(kāi)串口,該函數(shù)將根據(jù)制定的參數(shù)打開(kāi)串口,并創(chuàng)建此串口的讀線(xiàn)程,以實(shí)現(xiàn)串口數(shù)據(jù)實(shí)時(shí)異步讀操作。BOOL CCESeries:OpenPort(void * pOwner,UINT portNo , /*串口號(hào)*/UINT baud , /*波特率*/UINT parity , /*奇偶校驗(yàn)*/UINT databits , /*數(shù)據(jù)位*/UINT stopbits /*停止位*/)DCB commParam;TCHAR szPort15;ASSERT(pOwner!=NULL);m_pOwner = pOwner;/ 已經(jīng)打開(kāi)的話(huà),直接返回if (m_hComm !=

12、INVALID_HANDLE_VALUE)return TRUE;/設(shè)置串口名wsprintf(szPort, L"COM%d:", portNo);/打開(kāi)串口m_hComm = CreateFile(szPort,GENERIC_READ | GENERIC_WRITE, /允許讀和寫(xiě)0, /獨(dú)占方式(共享模式)NULL,OPEN_EXISTING, /打開(kāi)而不是創(chuàng)建(創(chuàng)建方式)0,NULL);if (m_hComm = INVALID_HANDLE_VALUE)/ 無(wú)效句柄,返回。TRACE(_T("CreateFile 返回?zé)o效句柄n");retu

13、rn FALSE;/ 得到打開(kāi)串口的當(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)制模式,此處必須設(shè)置TRUEcommParam.fParity = TRUE; / 支持奇偶校驗(yàn)commParam.ByteSize = databits;

14、/ 數(shù)據(jù)位,范圍:4-8commParam.Parity = parity; / 校驗(yàn)?zāi)J絚ommParam.StopBits = stopbits; / 停止位commParam.fOutxCtsFlow = FALSE; / No CTS output flow controlcommParam.fOutxDsrFlow = FALSE; / No DSR output flow controlcommParam.fDtrControl = DTR_CONTROL_ENABLE;/ DTR flow control typecommParam.fDsrSensitivity = FALSE

15、; / 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 replacementcommParam.fNull = FALSE; / Disable null strippingcommParam.fR

16、tsControl = RTS_CONTROL_ENABLE;/ RTS flow controlcommParam.fAbortOnError = FALSE; / 當(dāng)串口發(fā)生錯(cuò)誤,并不終止串口讀寫(xiě)/設(shè)置串口參數(shù)if (!SetCommState(m_hComm, &commParam)TRACE(_T("SetCommState error");/關(guān)閉串口CloseHandle (m_hComm);m_hComm = INVALID_HANDLE_VALUE;return FALSE;/設(shè)置串口讀寫(xiě)時(shí)間COMMTIMEOUTS CommTimeOuts;GetC

17、ommTimeouts (m_hComm, &CommTimeOuts);CommTimeOuts.ReadIntervalTimeout = MAXDWORD;CommTimeOuts.ReadTotalTimeoutMultiplier = 0;CommTimeOuts.ReadTotalTimeoutConstant = 0;CommTimeOuts.WriteTotalTimeoutMultiplier = 10;CommTimeOuts.WriteTotalTimeoutConstant = 1000;if(!SetCommTimeouts( m_hComm, &Co

18、mmTimeOuts )TRACE( _T("SetCommTimeouts 返回錯(cuò)誤") );/關(guān)閉串口CloseHandle (m_hComm);m_hComm = INVALID_HANDLE_VALUE;return FALSE;/指定端口監(jiān)測(cè)的事件集SetCommMask (m_hComm, EV_RXCHAR);/分配串口設(shè)備緩沖區(qū)SetupComm(m_hComm,512,512);/初始化緩沖區(qū)中的信息PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);CString strEvent;strEvent.Format

19、(L"Com_ReadCloseEvent%d",portNo);m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,strEvent);/創(chuàng)建串口讀數(shù)據(jù)監(jiān)聽(tīng)線(xiàn)程m_hReadThread =CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);TRACE(_T("串口打開(kāi)成功");m_bOpened = TRUE;return TRUE;/*函數(shù)介紹:關(guān)閉串口*入口參數(shù):(無(wú))*出口參數(shù):(無(wú))*返回值: (無(wú))*/該函數(shù)將退出串口讀

20、線(xiàn)程,并關(guān)閉串口句柄。void CCESeries:ClosePort()/表示串口還沒(méi)有打開(kāi)if (m_hComm = INVALID_HANDLE_VALUE)return ;/關(guān)閉讀線(xiàn)程CloseReadThread();/關(guān)閉串口CloseHandle (m_hComm);/關(guān)閉事件CloseHandle(m_hReadCloseEvent);m_hComm = INVALID_HANDLE_VALUE;m_bOpened = FALSE;/*函數(shù)介紹:往串口寫(xiě)入數(shù)據(jù)*入口參數(shù):buf :待寫(xiě)入數(shù)據(jù)緩沖區(qū)bufLen : 待寫(xiě)入緩沖區(qū)長(zhǎng)度*出口參數(shù):(無(wú))*返回值:TRUE:設(shè)置成功;

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

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

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

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

25、nitDialog()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 = (CComb

26、oBox*)GetDlgItem(IDC_CMB_DAT);CComboBox *pCmbComStopbits = (CComboBox*)GetDlgItem(IDC_CMB_STOP);/初始化數(shù)據(jù)/串口號(hào)pCmbComNo->ResetContent();for (int i=0; i < 10; i+)strItem.Format(L"%d",i+1);pCmbComNo->AddString(strItem);pCmbComNo->SetCurSel(0);/ com1:/波特率pCmbComBaud->ResetContent()

27、;pCmbComBaud->AddString(L"300");pCmbComBaud->AddString(L"600");pCmbComBaud->AddString(L"1200");pCmbComBaud->AddString(L"2400");pCmbComBaud->AddString(L"4800");pCmbComBaud->AddString(L"9600");pCmbComBaud->AddString(L&quo

28、t;19200");pCmbComBaud->AddString(L"38400");pCmbComBaud->AddString(L"43000");pCmbComBaud->AddString(L"56000");pCmbComBaud->AddString(L"57600");pCmbComBaud->AddString(L"115200");pCmbComBaud->SetCurSel(5) ; /9600/奇偶校驗(yàn)pCmbComParity

29、->ResetContent();pCmbComParity->AddString(L"None");pCmbComParity->AddString(L"Odd");pCmbComParity->AddString(L"Even");pCmbComParity->SetCurSel(0); / None/數(shù)據(jù)位pCmbComDatabits->ResetContent();pCmbComDatabits->AddString(L"8");pCmbComDatabits-&

30、gt;AddString(L"7");pCmbComDatabits->AddString(L"6");pCmbComDatabits->SetCurSel(0); /8/停止位pCmbComStopbits->ResetContent();pCmbComStopbits->AddString(L"1");pCmbComStopbits->AddString(L"1.5");pCmbComStopbits->AddString(L"2");pCmbComSto

31、pbits->SetCurSel(0); /1return TRUE;6.保存,編譯。程序出錯(cuò)了。錯(cuò)誤類(lèi)型如下:error C2509: 'OnInitDialog' : member function not declared in 'CDlgParams'這個(gè)函數(shù)我們沒(méi)有去聲明。在Dlgparams.h 文件中聲明該函數(shù),如下圖所示:重新編譯,錯(cuò)誤沒(méi)有了。7.接下來(lái)完成“連接”按鈕的單擊響應(yīng)函數(shù)。雙擊“連接”按鈕,添加代碼如下:void CDlgParams:OnBnClickedOk()/ TODO: 在此添加控件通知處理程序代碼/單擊按鈕事件CSt

32、ring strTmp;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(IDC_CMB_DAT);CComboBox *pCmbComStopbits = (CComboBox

33、*)GetDlgItem(IDC_CMB_STOP);pCmbComBaud->GetWindowTextW(strTmp);m_portNo = pCmbComNo->GetCurSel() + 1; /串口號(hào)m_baud = _wtoi(strTmp); /波特率m_parity = pCmbComParity->GetCurSel(); /奇偶校驗(yàn)pCmbComDatabits->GetWindowTextW(strTmp);m_databits = _wtoi(strTmp); /數(shù)據(jù)位m_stopbits = pCmbComStopbits->GetCu

34、rSel(); /停止位/關(guān)閉對(duì)話(huà)框OnOK();8.到了這,CDlgParams 類(lèi)的操作就基本完成了。接下來(lái)為CBomcTestDlg 類(lèi)添加一個(gè)CCESeries對(duì)象指針。public:/ 串口對(duì)象指針CCESeries *m_pSerial;然后在BomcTestDlg類(lèi)的頭文件中添加CCESeries類(lèi)的頭文件引用,如下:#include "CESeries.h"9.接下來(lái)完成“連接串口設(shè)備”按鈕單擊響應(yīng)函數(shù),如下:void CBomcTestDlg:OnBnClickedBtnConn()/判斷串口是否已經(jīng)打開(kāi)if (m_pSerial != NULL)m_pS

35、erial->ClosePort();delete m_pSerial;m_pSerial = NULL;/串口參數(shù)輸入對(duì)話(huà)框CDlgParams dlgParams;if (dlgParams.DoModal() = IDOK)/新建串口通訊對(duì)象m_pSerial = new CCESeries();/打開(kāi)串口if (m_pSerial->OpenPort(this,dlgParams.m_portNo,dlgParams.m_baud,dlgParams.m_parity,dlgParams.m_databits,dlgParams.m_stopbits)AfxMessageBox(L"

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論