[WinCE]Windows CE下的串口通訊執行個體

來源:互聯網
上載者:User
Windows CE下的串口通訊執行個體 串列通訊是目前電腦、通訊和控制領域最基本的通訊方式。在CSDN的“嵌入式開發/WINCE”社區中,經常有人提問該到哪找串口通訊例子,其實這個問題我自己也問過。:)而一般的回答是給你提供一個Pocket PC 2002的SDK例子程式。但到底SDK的程式和MFC的結構有很大的不同,對於想用MFC編寫通訊程式的人來說也不是很便利。另一方面,由於Windows CE是一個基於Unicode的作業系統,並且Windows CE不支援Windows下常用的串列通訊重疊I/O方式(OVERLAPPED),因此編寫Windows CE下的串口通訊類有一些與案頭Windows不同的地方。以下是我從SDK程式改寫而來的MFC例子程式,希望能和致力於WINCE開發的朋友多多交流,由於本人才疏學淺,程式中有許多不完善的地方,請大家指正。我的程式是基於“主動發送請求,被動接收響應”的假設,因此我只設定了一個接收資料的線程。感謝“嵌入式開發/WINCE”社區為我提供SDK例子的朋友,感謝CSDN上所有熱心的朋友,祝願中國的軟硬體水平能早日擠身世界一流。 標頭檔Serial.h// Serial.h: interface for the CSerial class.//////////////////////////////////////////////////////////////////////// #if !defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)#define AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_ #if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000 DWORD WINAPI ReadPortThread(LPVOID lpvoid); //讀資料線程 class CSerial {public:       BOOL InitCommTimeouts(); //設定逾時參數       BOOL InitDCB(); //配置串口       BOOL m_bConnected;       BOOL ClosePort(HANDLE hCommPort); //關閉串口       DWORD WritePort(TCHAR *buf,DWORD dwBytesToWrite); //寫資料       BOOL OpenPort(LPTSTR lpszPortName); //開啟串口       CSerial();       HANDLE hReadThread;       virtual ~CSerial();   }; #endif // !defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)   源檔案:Serial.cpp// Serial.cpp: implementation of the CSerial class.//////////////////////////////////////////////////////////////////////// #include "stdafx.h"#include "Serial.h" #ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif HANDLE hPort;CString strInChar; //////////////////////////////////////////////////////////////////////// Construction/Destruction////////////////////////////////////////////////////////////////////// CSerial::CSerial(){ } CSerial::~CSerial(){       if(hPort != INVALID_HANDLE_VALUE)              ClosePort(hPort);} BOOL CSerial::OpenPort(LPTSTR lpszPortName){       DWORD dwError,               dwThreadID;              if(hPort)       {              return FALSE;       }        //開啟串口       hPort = CreateFile (lpszPortName, GENERIC_READ | GENERIC_WRITE,                                           0, NULL, OPEN_EXISTING,0, NULL);       //如果開啟連接埠出錯, 返回FALSE       if ( hPort == INVALID_HANDLE_VALUE )        {              //不能開啟連接埠              CString strError;              strError.Format(_T("Unable to open %s, Error No.=%d"),                                            lpszPortName, GetLastError());               MessageBox (NULL, strError,      TEXT("Error"), MB_OK);               return FALSE;       }        //指定連接埠監測的事件集       SetCommMask (hPort, EV_RXCHAR);       //分配裝置緩衝區       SetupComm(hPort,512,512);       //初始化緩衝區中的資訊       PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);        //配置序列埠       if(!InitDCB())              return FALSE;        //設定連接埠逾時值       if(!InitCommTimeouts())              return FALSE;        //設定連接埠上指定訊號的狀態       // SETDTR: 發送DTR (data-terminal-ready)訊號       // SETRTS: 發送RTS (request-to-send)訊號       EscapeCommFunction (hPort, SETDTR);       EscapeCommFunction (hPort, SETRTS);        //建立一個從串口讀取資料的線程       if (hReadThread = CreateThread (NULL, 0, ReadPortThread, 0, 0,                                                                 &dwThreadID))       {       }       else       {              //不能建立線程              MessageBox (NULL, TEXT("Unable to create the read thread"),                                    TEXT("Error"), MB_OK);              dwError = GetLastError ();              return FALSE;       }        m_bConnected=TRUE;              return TRUE;} DWORD CSerial::WritePort(TCHAR *buf,DWORD dwCharToWrite){       BOOL fWriteState;       DWORD dwBytesWritten;        //寫入資料       fWriteState=WriteFile(hPort,buf,dwCharToWrite*sizeof(TCHAR),&dwBytesWritten,NULL);       if(!fWriteState)       {              //不能寫資料              MessageBox(NULL,TEXT("Can't Write String to Comm"),TEXT("Error"),MB_OK);              dwBytesWritten=0;       }        return dwBytesWritten;} DWORD WINAPI ReadPortThread(LPVOID lpvoid){       BOOL fReadState;       DWORD dwCommModemStatus;        DWORD dwLength;       COMSTAT ComStat;       DWORD dwErrorFlags;        while (hPort != INVALID_HANDLE_VALUE)        {              //等待串口的事件發生              WaitCommEvent (hPort, &dwCommModemStatus, 0);               if (dwCommModemStatus & EV_RXCHAR)               {                     ClearCommError(hPort,&dwErrorFlags,&ComStat);                     //cbInQue返回在串列驅動程式輸入隊列中的字元數                     dwLength=ComStat.cbInQue;                      if(dwLength>0)                     {                            //從串口讀取資料                            TCHAR* buf=new TCHAR[256];                            fReadState=ReadFile(hPort,buf,dwLength,&dwLength,NULL);                            if(!fReadState)                            {                                   //不能從串口讀取資料                                   MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);                            }                            else                            {                                   //把資料賦值給全域變數                                   strInChar=buf;                            }                            delete[] buf;                     }                   }                            GetCommModemStatus (hPort, &dwCommModemStatus);       }        return 0;} BOOL CSerial::ClosePort(HANDLE hCommPort){       if (hCommPort != INVALID_HANDLE_VALUE)       {              //設定串連屬性為FALSE              m_bConnected=FALSE;               //結束線程中WaitCommEvent的等待              SetCommMask(hPort,0);                            //阻塞至線程停止              if(hReadThread)              {                     TerminateThread(hReadThread,0);                     CloseHandle(hReadThread);              }                            //清除連接埠上指定訊號的狀態              EscapeCommFunction(hPort,CLRDTR);              EscapeCommFunction(hPort,CLRRTS);              //清除驅動程式內部的發送和接收隊列              PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);               //關閉串口              CloseHandle (hCommPort);              hCommPort = INVALID_HANDLE_VALUE;               return TRUE;       }       else       {              return TRUE;       }} BOOL CSerial::InitDCB(){       DCB PortDCB;       DWORD dwError;        PortDCB.DCBlength = sizeof (DCB);             //得到連接埠的預設設定資訊       GetCommState (hPort, &PortDCB);        //改變DCB結構設定       PortDCB.BaudRate = 19200;               //傳輸速率        PortDCB.fBinary = TRUE;                 //Win32不支援非二進位串列傳輸模式,必須為TRUE        PortDCB.fParity = TRUE;                 //啟用同位        PortDCB.fOutxCtsFlow = TRUE;            //序列埠的輸出由CTS線控制       PortDCB.fOutxDsrFlow = FALSE;           //關閉序列埠的DSR流量控制        PortDCB.fDtrControl = DTR_CONTROL_ENABLE;   //啟用DTR線       PortDCB.fDsrSensitivity = FALSE;        //如果設為TRUE將忽略任何輸入的位元組,除非DSR線被啟用        //PortDCB.fTXContinueOnXoff = TRUE;       //當為TRUE時,如果接收緩衝區已滿且驅動程式已傳送XOFF字元,將使驅動程式停止傳輸字元       PortDCB.fTXContinueOnXoff = FALSE;       PortDCB.fOutX = FALSE;                  //設為TRUE指定XON/XOFF控制被用於控制串列輸出        PortDCB.fInX = FALSE;                   //設為TRUE指定XON/XOFF控制被用於控制串列輸入        PortDCB.fErrorChar = FALSE;             //WINCE串列驅動程式的預設執行將忽略這個欄位        PortDCB.fNull = FALSE;                  //設為TRUE將使串列驅動程式忽略收到的空位元組        PortDCB.fRtsControl = RTS_CONTROL_ENABLE;   //啟用RTS線        PortDCB.fAbortOnError = FALSE;          //WINCE串列驅動程式的預設執行將忽略這個欄位       PortDCB.ByteSize = 8;                   //每位元組的位元        PortDCB.Parity = NOPARITY;              //無同位        PortDCB.StopBits = ONESTOPBIT;          //每位元組一位停止位         //根據DCB結構配置連接埠        if (!SetCommState (hPort, &PortDCB))       {              //不能配置序列埠              MessageBox (NULL, TEXT("Unable to configure the serial port"),                                    TEXT("Error"), MB_OK);              dwError = GetLastError ();              return FALSE;       }        return TRUE;} BOOL CSerial::InitCommTimeouts(){       COMMTIMEOUTS CommTimeouts;       DWORD dwError;        //得到逾時參數       GetCommTimeouts (hPort, &CommTimeouts);        //改變COMMTIMEOUTS結構設定       CommTimeouts.ReadIntervalTimeout = MAXDWORD;        CommTimeouts.ReadTotalTimeoutMultiplier = 0;        CommTimeouts.ReadTotalTimeoutConstant = 0;           CommTimeouts.WriteTotalTimeoutMultiplier = 10;        CommTimeouts.WriteTotalTimeoutConstant = 1000;            //設定連接埠逾時值        if (!SetCommTimeouts (hPort, &CommTimeouts))       {              //不能設定逾時值              MessageBox (NULL, TEXT("Unable to set the time-out parameters"),                                    TEXT("Error"), MB_OK);              dwError = GetLastError ();              return FALSE;       }        return TRUE;} 以上類代碼在eMbedded Visual C++4.0和基於ARM9的三星S3C2410開發板(運行Windows CE.NET 4.1)上測試通過。Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=17885
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.