日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

    <mark id="r87n3"><listing id="r87n3"></listing></mark>
    <span id="r87n3"></span>

      <menu id="r87n3"></menu>
      <ruby id="r87n3"><dd id="r87n3"></dd></ruby>
      歡迎訪問 生活随笔!

      生活随笔

      當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

      编程问答

      串口类的编写

      發(fā)布時間:2024/8/22 编程问答 27 豆豆
      生活随笔 收集整理的這篇文章主要介紹了 串口类的编写 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

      CSerial類只有2個文件,分別是CSerial.cpp和CSerial.h。

      ?

      CSerial.h內(nèi)容如下:

      ?

      1 /***************************************************
      2 *作 者:溫子祺
      3 *聯(lián)系方式:wenziqi@hotmail.com
      4 *說 明:CSerial.h
      5 提供外部調(diào)用的函數(shù)
      6 Open(),Close(),Send()
      7 接收數(shù)據(jù)時通過消息來實現(xiàn)
      8 ***************************************************/
      9 #ifndef __CSERIAL_H__
      10 ?#define __CSERIAL_H__
      11 ?#pragma once
      12
      13 ?class CSerial
      14 {
      15 ?public:
      16 CSerial(void);
      17 virtual~CSerial(void);
      18
      19 BOOL Open(CWnd *pPortOwner,
      20 UINT portnr,
      21 UINT baud,
      22 UINT parity,
      23 UINT databits,
      24 UINT stopbits,
      25 UINT rxdmsg);
      26
      27 BOOL Close(void);
      28
      29 UINT Send(UCHAR *pbuf,UINT len);
      30
      31 ?protected:
      32
      33 BOOL Ready(void) const;
      34 BOOL CreateThreadAndEvent(void);
      35 ?static
      36 DWORD RecvThread(LPVOID lpArg);
      37
      38 private:
      39 CWnd * m_pOwner;
      40 BOOL m_bInit;
      41
      42 HANDLE m_hSerial;
      43 HANDLE m_hRecvEvent;
      44 HANDLE m_hRecvExitEvent;
      45
      46 UINT m_unRxdMsg;
      47 };
      48 #endif

      ?

      CSerial.cpp代碼如下:

      ?

      1 /***************************************************
      2 *作 者:溫子祺
      3 *聯(lián)系方式:wenziqi@hotmail.com
      4 *說 明:CSerial.cpp
      5 提供外部調(diào)用的函數(shù)
      6 Open(),Close(),Send()
      7 接收數(shù)據(jù)時通過消息來實現(xiàn)
      8 ***************************************************/
      9 #include "StdAfx.h"
      10 #include "CSerial.h"
      11 #include <assert.h> //使用斷言
      12
      13 CSerial::CSerial(void)
      14 {
      15 m_pOwner=NULL;
      16 m_bInit=FALSE;
      17 m_hRecvEvent=NULL;
      18 m_hRecvExitEvent=NULL;
      19 m_hSerial=NULL;
      20 m_bInit=FALSE;
      21 }
      22
      23 CSerial::~CSerial(void)
      24 {
      25 Close();
      26 }
      27
      28 BOOL CSerial::Ready(void)const
      29 {
      30 return m_bInit;
      31 }
      32
      33 BOOL CSerial::Close(void)
      34 {
      35
      36 if (m_hSerial)
      37 {
      38 CloseHandle(m_hSerial);
      39 m_hSerial=NULL;
      40 }
      41
      42 if (m_hRecvEvent)
      43 {
      44 CloseHandle(m_hRecvEvent);
      45 m_hRecvEvent=NULL;
      46 }
      47
      48 if (m_hRecvExitEvent)
      49 {
      50 SetEvent(m_hRecvExitEvent); //退出線程
      51 Sleep(10);
      52 CloseHandle(m_hRecvExitEvent);
      53 m_hRecvExitEvent=NULL;
      54 }
      55
      56 if (m_bInit)
      57 {
      58 m_bInit=FALSE;
      59 }
      60
      61 if (m_pOwner)
      62 {
      63 m_pOwner=NULL;
      64 }
      65
      66 return TRUE;
      67 }
      68
      69 BOOL CSerial::Open(CWnd *pPortOwner,
      70 UINT portnr,
      71 UINT baud,
      72 UINT parity,
      73 UINT databits,
      74 UINT stopbits,
      75 UINT rxdmsg)
      76 {
      77 assert(NULL != pPortOwner);
      78
      79 m_pOwner = pPortOwner;
      80
      81 if (Ready())
      82 {
      83 Close();
      84 }
      85
      86 COMMTIMEOUTS CommTimeOuts;
      87 DCB dcb;
      88
      89 LPSTR sz= new CHAR[64];
      90 LPWSTR wsz= new WCHAR[64];
      91
      92 // 打開串口
      93 //wprintf_s(wsz,64,"COM%d",portnr);//用wprintf無效
      94 sprintf_s(sz,64,"COM%d",portnr);
      95 MultiByteToWideChar(CP_ACP,
      96 0,
      97 sz,
      98 64,
      99 wsz,
      100 64);
      101
      102 m_hSerial = CreateFile(wsz,
      103 GENERIC_READ | GENERIC_WRITE,
      104 0,
      105 0,
      106 OPEN_EXISTING,
      107 0,
      108 0);
      109
      110 delete []sz;
      111 delete []wsz;
      112
      113 if(m_hSerial == INVALID_HANDLE_VALUE)
      114 {
      115 return FALSE;
      116 }
      117
      118 GetCommState(m_hSerial, &dcb); /* 讀取串口的DCB */
      119 dcb.BaudRate = baud; //波特率
      120 dcb.ByteSize = databits; //數(shù)據(jù)位
      121 dcb.Parity = parity; //校驗位
      122 dcb.StopBits = stopbits; //停止位
      123
      124 dcb.fParity = FALSE; /* 禁止奇偶校驗 */
      125 dcb.fBinary = TRUE;
      126 dcb.fDtrControl = 0; /* 禁止流量控制 */
      127 dcb.fRtsControl = 0;
      128 dcb.fOutX = 0;
      129 dcb.fInX = 0;
      130 dcb.fTXContinueOnXoff = 0;
      131 dcb.EvtChar='q'; // 這個一定要,否則大于127的數(shù)值會接收不了啊
      132
      133 //設(shè)置狀態(tài)參數(shù)
      134 SetCommMask(m_hSerial, EV_RXFLAG|EV_RXCHAR); /* 串口事件:接收到一個字符 */
      135 SetupComm(m_hSerial, 1024, 1024); /* 設(shè)置接收與發(fā)送的緩沖區(qū)大小 */
      136
      137 if(!SetCommState(m_hSerial, &dcb)) /* 設(shè)置串口的DCB */
      138 {
      139 return FALSE;
      140 }
      141
      142 //設(shè)置超時參數(shù)
      143 GetCommTimeouts(m_hSerial, &CommTimeOuts);
      144 CommTimeOuts.ReadIntervalTimeout = 100; /* 接收字符間最大時間間隔 */
      145 CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
      146 CommTimeOuts.ReadTotalTimeoutConstant = 100; /* 讀數(shù)據(jù)總超時常量 */
      147 CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
      148 CommTimeOuts.WriteTotalTimeoutConstant = 0;
      149
      150 if(!SetCommTimeouts(m_hSerial, &CommTimeOuts))
      151 {
      152 return FALSE;
      153 }
      154
      155 PurgeComm(m_hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); /* 清除收/發(fā)緩沖區(qū) */
      156
      157 if (!CreateThreadAndEvent())
      158 {
      159 return FALSE;
      160 }
      161
      162 m_unRxdMsg=rxdmsg;
      163
      164 m_bInit = TRUE;
      165
      166 return TRUE;
      167 }
      168 BOOL CSerial::CreateThreadAndEvent(void)
      169 {
      170 m_hRecvExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* 創(chuàng)建串口接收線程退出事件*/
      171
      172 if (NULL==m_hRecvExitEvent)
      173 {
      174 return FALSE;
      175 }
      176
      177 ResetEvent(m_hRecvExitEvent); //設(shè)置線程沒有退出
      178
      179 HANDLE hRecvThread=NULL;
      180 DWORD dwThreadID =0;
      181
      182 // 創(chuàng)建串口接收線程
      183 hRecvThread=CreateThread(0,
      184 0,
      185 (LPTHREAD_START_ROUTINE)RecvThread,
      186 this,
      187 0,
      188 &dwThreadID);
      189
      190 if (NULL==hRecvThread)
      191 {
      192 return FALSE;
      193 }
      194
      195 CloseHandle(hRecvThread);
      196 hRecvThread=NULL;
      197
      198 return TRUE;
      199 }
      200
      201 UINT CSerial::Send(UCHAR *pbuf,UINT len)
      202 {
      203 if (!Ready())
      204 {
      205 //AfxMessageBox(_T("請確保串口已正常打開"));
      206 return 0;
      207 }
      208
      209 BOOL rt=FALSE;
      210
      211 DWORD dwBytesSend=0,dwCnt=0;
      212
      213 while (len>dwCnt)
      214 {
      215 rt=WriteFile(m_hSerial,pbuf+dwCnt,len-dwCnt,&dwBytesSend,NULL);
      216
      217 if (!rt)
      218 {
      219 return FALSE;
      220 }
      221
      222 dwCnt+=dwBytesSend;
      223
      224 if (len > dwCnt)
      225 {
      226 Sleep(100); //有可能I/O掛起
      227 }
      228 }
      229
      230 return (UINT)dwCnt;
      231 }
      232
      233 DWORD CSerial::RecvThread(LPVOID lpArg)
      234 {
      235
      236 assert(NULL != lpArg);
      237
      238 CSerial *pArg=(CSerial *)lpArg;
      239
      240 assert(NULL != pArg);
      241
      242 DWORD dwBytesRecv=0;
      243 DWORD dwError=0;
      244 UCHAR ucDat=0;
      245 COMSTAT ComStat;
      246
      247 memset(&ComStat,0,sizeof(ComStat));
      248
      249 while (1)
      250 {
      251 if (WaitForSingleObject(pArg->m_hRecvExitEvent,0)==WAIT_OBJECT_0)
      252 {
      253 break; //線程退出
      254 }
      255
      256 if (pArg->Ready())
      257 {
      258 ClearCommError(pArg->m_hSerial,&dwError,&ComStat);
      259
      260 if (0 == ComStat.cbInQue)
      261 {
      262 Sleep(1);
      263 continue;
      264 }
      265
      266 if (ReadFile(pArg->m_hSerial,&ucDat,1,&dwBytesRecv,NULL))
      267 {
      268 if (dwBytesRecv)
      269 {
      270 ::SendMessage((pArg->m_pOwner)->m_hWnd,
      271 pArg->m_unRxdMsg,
      272 (WPARAM)ucDat,
      273 NULL);
      274 }
      275 }
      276 }
      277
      278 Sleep(1);
      279
      280 }
      281
      282 Sleep(10); //讓線程安全退出
      283
      284 return 0;
      285 }
      286

      ?

      ?

      轉(zhuǎn)載于:https://www.cnblogs.com/wenziqi/archive/2010/07/01/1769156.html

      總結(jié)

      以上是生活随笔為你收集整理的串口类的编写的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

      如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。