




已阅读5页,还剩35页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
CSerialPort类解析CSerialPort类的功能及成员函数介绍CSerialPort类是免费提供的串口累,Codeguru是一个非常不错的源代码网站CSerialPort类支持线连接(非MODEM)的串口编程操作。CSerialPort类是基于多线程的,其工作流程如下:首先设置好串口参数,再开启串口检测工作线程,串口检测工作线程检测到串口接收到的数据、流控制事件或其他串口事件后,就以消息方式通知主程序,激发消息处理函数来进行数据处理,这是对接受数据而言的,发送数据可直接向串口发送。CSerialPort类定义的消息如表消息名称消息号功能说明WM_COMM_BREAK_DETECTEDWM_USER+1检测到输入中断WM_COMM_CTS_DETECTEDWM_USER+2检测到CTS(清除发送)信号状态改变WM_COMM_DSR_DETECTEDWM_USER+3检测到DSR(数据设备准备就绪)信号状态改变WM_COMM_ERR_DETECTEDWM_USER+4发生线状态错误(包括CE_FRAME,CE_OVERRUN,和CE_RXPARITY)WM_COMM_RING_DETECTEDWM_USER+5检测到响铃指示信号WM_COMM_RLSD_DETECTEDWM_USER+6检测到RLSD(接收线信号)状态改变WM_COMM_RXCHARWM_USER+7接收到一个字符并已放入接受缓冲区WM_COMM_RXFLAG_DETECTEDWM_USER+8检测到接受到字符(该字符已放入接受缓冲区)事件WM_COMM_TXEMPTY_DETECTEDWM_USER+9检测到发送缓冲区最后一个字符已经被发送介绍几个经常用到的函数:1、串口初始化函数InitPortBOOLCSerialPort:InitPort(CWnd*pPortOwner,/theowner(CWnd)oftheport(receivesmessage)UINTportnr,/portnumber(1.4)UINTbaud,/baudratecharparity,/parityUINTdatabits,/databitsUINTstopbits,/stopbitsDWORDdwCommEvents,/EV_RXCHAR,EV_CTSetcUINTwritebuffersize)/sizetothewritebufferassert(portnr0&portnr0&portnrSuspendThread();returnTRUE;4、关闭串口函数ClosePort()该函数功能是关闭串口,释放串口资源,调用该函数后,如果要继续使用串口,还需要调用InitPort()函数5、通过串口发送字符/写串口函数WriteToPort()该函数完成写串口功能,即向串口发送字符。/WriteastringtotheportvoidCSerialPort:WriteToPort(char*string)assert(m_hComm!=0);memset(m_szWriteBuffer,0,sizeof(m_szWriteBuffer);strcpy(m_szWriteBuffer,string);/seteventforwriteSetEvent(m_hWriteEvent);以上是常用的函数介绍,熟悉该类的使用后,可以仔细看看其他函数,对上面介绍的函数,在对串口资源的使用上要记住一下三点:l打开串口用调用InitPort()和StartMonitoring();关闭串口用StopMonitoring()和ClosePort()而且以上函数的调用顺序不能乱l通过串口发送字符调用函数WriteToPort()l接受串口收到的字符需要自己编写WM_COMM_RXCHAR消息处理函数,需要手工添加。操作:首先,需要操作一个串口,所以只需要定义1个类对象就可以了,如要操作多个串口,则要为每个串口均定一个类对象,这可以通过数据方式来实现,这里定义的类对象为m_SerialPort,再定义一个布尔变量m_bSerialPortOpened用来标志串口是否打开。在CserialPort类中有多个串口事件可以响应,在一般串口编程中,只需要处理WM_COMM_RXCHAR消息就可以了,该类所有的消息均需要人工添加消息处理函数,将处理函数名定义为OnComm(),首先在SerialPortTestDlg.h(头文件)中添加串口字符接受消息WM_COMM_RXCHAR(串口接受缓冲区内有一个字符)的响应函数声明:/Generatedmessagemapfunnctions/AFX_MSG(CSCportTestView)afx_msglongOnComm(WPARAMch,LPARAMport);/AFX_MSG然后在,SerilPortTestDlg.cpp文件中进行WM_COMM_RXCHAR消息映射BEGIN_MESSAE_MAP(CSerialPortTestDlg,CDialog)s/AFX_MSG_MAP(CSerialPortTestDlg)ON_MESSAGE(WM_COMM_RXCHAR,OnComm)/AFX_MSG_MAPEND_MESSAGE_MAP()接着,在SerialPortTestDlg.cpp文件中加入函数OnComm()的实现,并在其中完成对节诶受到的字符的处理,将接收到的字符显示在接受编辑框中:longCSerialPortTestDlg:OnComm(WPARAMch,LPARAMport) m_strEditReceiveMsg+=ch; UpdateData(FLASE);/将接收到的字符显示在接受编辑框中 returne0;说明:WPARAM、LPARAM类型是多态数据类型,在WIN32中为32位,支持多种数据类型,根据需要自动适应,这样,程序有很强的适应性,再次,我们可以分贝理解为char和integer类型数据,每当串口接受缓冲区内有一个字符时,就会产生一个WM_COMM_RXCHAR消息,除法OnComm()函数,这时就可以在函数中进行数据处理,所以,这个消息就是整个程序的源头。虽然CSerialPort类是一个非常好的类,但毕竟只是集中了作者一个人的智慧和经验,他也有许多缺陷,n原类只能发送字符(ASCII文本)不能处理二进制发送(也就是不能发送0X00)n该类不能很好的释放串口n存在内存泄漏可以进行如下改进改进一、ASCII文本和二进制数据发送方式兼容CSerialPort类中只有一个发送函数WriteToPort()/Writeastringtotheport/voidCSerialPort:WriteToPort(char*string) assert(m_hComm!=0); memset(m_szWriteBuffer,0,sizeof(m_szWriteBuffer); strcpy(m_szWriteBuffer,string); /seteventforwrite SetEvent(m_hWriteEvent);调用上面的函数就只能用字符串方式,而c语言中,空字符(NULL,其中ASCII码值为0,即通常所说的十六禁止0x00字符),是串结束符,当检测到NULL字符后,就认为该字符串结束了,所以0x00字符以ASCII文本方式是不能从串口发送出去的,那么解决这一问题的方法就是用二进制发送,其实这里说的二进制,只不过是不以我们通常所说的“可见”或“能显示的字符”发送,比如,要发如下的一组值:charchSend5=0x33,0x96,0x00,0x31,0xf1;下面来对类做一些改进,解决这个问题,原理就是用字符数据来发送数据,并在发送时指定其长度,这样,数据没有发送完,发送过程就不会停止,CSerialPort类是用API函数编写的在,只要在WriteFile()函数中指定其实际要发送的长度,就可以将数据全部发送出去:实现步骤如下:1、在SerialPort.h文件中为CSerialPort类添加一个整形public成员变量,:intm_nWriteSize;用于指定发送字符数据的长度添加三个发送函数h文件:cppview plaincopy1. #ifndef_SERIALPORT_H_2. #define_SERIALPORT_H_3. 4. #defineWM_COMM_BREAK_DETECTEDWM_USER+1/Abreakwasdetectedoninput.5. #defineWM_COMM_CTS_DETECTEDWM_USER+2/TheCTS(clear-to-send)signalchangedstate.6. #defineWM_COMM_DSR_DETECTEDWM_USER+3/TheDSR(data-set-ready)signalchangedstate.7. #defineWM_COMM_ERR_DETECTEDWM_USER+4/Aline-statuserroroccurred.Line-statuserrorsareCE_FRAME,CE_OVERRUN,andCE_RXPARITY.8. #defineWM_COMM_RING_DETECTEDWM_USER+5/Aringindicatorwasdetected.9. #defineWM_COMM_RLSD_DETECTEDWM_USER+6/TheRLSD(receive-line-signal-detect)signalchangedstate.10. #defineWM_COMM_RXCHARWM_USER+7/Acharacterwasreceivedandplacedintheinputbuffer.11. #defineWM_COMM_RXFLAG_DETECTEDWM_USER+8/Theeventcharacterwasreceivedandplacedintheinputbuffer.12. #defineWM_COMM_TXEMPTY_DETECTEDWM_USER+9/Thelastcharacterintheoutputbufferwassent.13. 14. 15. classCSerialPort16. 17. public:18. voidClosePort();19. voidWriteToPort(LPCTSTRstring,intn);20. voidWriteToPort(LPCTSTRstring);21. voidWriteToPort(char*string,intn);22. CSerialPort();23. virtualCSerialPort();24. BOOLInitPort(CWnd*pPortOwner,/theowner(CWnd)oftheport(receivesmessage)25. UINTportnr,/portnumber(1.4)26. UINTbaud,/baudrate27. charparity,/parity28. UINTdatabits,/databits29. UINTstopbits,/stopbits30. DWORDdwCommEvents,/EV_RXCHAR,EV_CTSetc31. UINTwritebuffersize);/sizetothewritebuffer32. 33. BOOLStartMonitoring();34. BOOLRestartMonitoring();35. BOOLStopMonitoring();36. DWORDGetWriteBufferSize();37. DWORDGetCommEvents();38. DCBGetDCB();39. 40. voidWriteToPort(char*string);41. intm_nWriteSize;42. 43. protected:44. /protectedmemberfunctions45. voidProcessErrorMessage(char*ErrorText);46. staticUINTCommThread(LPVOIDpParam);47. staticvoidReceiveChar(CSerialPort*port,COMSTATcomstat);48. staticvoidWriteChar(CSerialPort*port);49. 50. /thread51. CWinThread*m_Thread;52. 53. /synchronisationobjects54. CRITICAL_SECTIONm_csCommunicationSync;55. BOOLm_bThreadAlive;56. 57. /handles58. HANDLEm_hShutdownEvent;59. HANDLEm_hComm;60. HANDLEm_hWriteEvent;61. 62. /Eventarray.63. /Oneelementisusedforeachevent.Therearetwoeventhandlesforeachport.64. /AWriteeventandareceivecharactereventwhichislocatedintheoverlappedstructure(m_ov.hEvent).65. /Thereisageneralshutdownwhentheportisclosed.66. HANDLEm_hEventArray3;67. 68. /structures69. OVERLAPPEDm_ov;70. COMMTIMEOUTSm_CommTimeouts;71. DCBm_dcb;72. 73. /ownerwindow74. CWnd*m_pOwner;75. 76. /misc77. UINTm_nPortNr;78. char*m_szWriteBuffer;79. DWORDm_dwCommEvents;80. DWORDm_nWriteBufferSize;81. ;82. 83. #endif_SERIALPORT_H_cpp文件:cppview plaincopy1. CSerialPort.cpp2. /*3. 4. *FILENAMECSerialPort.cpp5. 6. *7. 8. *PURPOSEThisclasscanread,writeandwatchoneserialport.9. 10. *Itsendsmessagestoitsownerwhensomethinghappendsontheport11. 12. *Theclasscreatesathreadforreadingandwritingsothemain13. 14. *programisnotblocked.15. 16. *17. 18. *CREATIONDATE15-09-199719. 20. *LASTMODIFICATION12-11-199721. 22. *23. 24. *AUTHORRemonSpekreijse25. 26. *27. 28. *29. 30. */31. 32. 33. #includestdafx.h34. 35. #includeCSerialPort.h36. 37. #include38. 39. 40. /41. 42. /Constructor43. 44. /45. 46. CSerialPort:CSerialPort()47. 48. 49. 50. m_hComm=NULL;51. 52. 53. /initializeoverlappedstructurememberstozero54. 55. m_ov.Offset=0;56. 57. m_ov.OffsetHigh=0;58. 59. 60. /createevents61. 62. m_ov.hEvent=NULL;63. 64. m_hWriteEvent=NULL;65. 66. m_hShutdownEvent=NULL;67. 68. 69. m_szWriteBuffer=NULL;70. 71. 72. m_bThreadAlive=FALSE;73. 74. 75. m_nWriteSize=0;76. 77. 78. 79. 80. /81. 82. /Deletedynamicmemory83. 84. /85. 86. CSerialPort:CSerialPort()87. 88. 89. 90. do91. 92. 93. 94. SetEvent(m_hShutdownEvent);95. 96. 97. while(m_bThreadAlive);98. 99. 100. TRACE(Threadendedn);101. 102. 103. deletem_szWriteBuffer;104. 105. 106. 107. 108. /109. 110. /Initializetheport.Thiscanbeport1to4.111. 112. /113. 114. BOOLCSerialPort:InitPort(CWnd*pPortOwner,/theowner(CWnd)oftheport(receivesmessage)115. 116. UINTportnr,/portnumber(1.4)117. 118. UINTbaud,/baudrate119. 120. charparity,/parity121. 122. UINTdatabits,/databits123. 124. UINTstopbits,/stopbits125. 126. DWORDdwCommEvents,/EV_RXCHAR,EV_CTSetc127. 128. UINTwritebuffersize)/sizetothewritebuffer129. 130. 131. 132. assert(portnr0&portnr5);133. 134. assert(pPortOwner!=NULL);135. 136. 137. /ifthethreadisalive:Kill138. 139. if(m_bThreadAlive)140. 141. 142. 143. do144. 145. 146. 147. SetEvent(m_hShutdownEvent);148. 149. 150. while(m_bThreadAlive);151. 152. TRACE(Threadendedn);153. 154. 155. 156. 157. /createevents158. 159. if(m_ov.hEvent!=NULL)160. 161. ResetEvent(m_ov.hEvent);162. 163. else164. 165. m_ov.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);166. 167. 168. if(m_hWriteEvent!=NULL)169. 170. ResetEvent(m_hWriteEvent);171. 172. else173. 174. m_hWriteEvent=CreateEvent(NULL,TRUE,FALSE,NULL);175. 176. 177. if(m_hShutdownEvent!=NULL)178. 179. ResetEvent(m_hShutdownEvent);180. 181. else182. 183. m_hShutdownEvent=CreateEvent(NULL,TRUE,FALSE,NULL);184. 185. 186. /initializetheeventobjects187. 188. m_hEventArray0=m_hShutdownEvent;/highestpriority189. 190. m_hEventArray1=m_ov.hEvent;191. 192. m_hEventArray2=m_hWriteEvent;193. 194. 195. /initializecriticalsection196. 197. InitializeCriticalSection(&m_csCommunicationSync);198. 199. 200. /setbuffersizeforwritingandsavetheowner201. 202. m_pOwner=pPortOwner;203. 204. 205. if(m_szWriteBuffer!=NULL)206. 207. deletem_szWriteBuffer;208. 209. m_szWriteBuffer=newcharwritebuffersize;210. 211. 212. m_nPortNr=portnr;213. 214. 215. m_nWriteBufferSize=writebuffersize;216. 217. m_dwCommEvents=dwCommEvents;218. 219. 220. BOOLbResult=FALSE;221. 222. char*szPort=newchar50;223. 224. char*szBaud=newchar50;225. 226. 227. /nowitcritical!228. 229. EnterCriticalSection(&m_csCommunicationSync);230. 231. 232. /iftheportisal
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 大学生文员实习总结
- 大学生在中国平安保险公司实习报告范文 -管理资料
- 大学班委辞职申请书怎么写
- 大学校园文化活动策划书
- 外墙保温劳务分包合同简单版
- 建设工程epc总包合同范本
- 供应钢管架出租合同范本
- 分期公司合同转让协议书
- 公司收回股份协议书范本
- 进口贸易融资业务合同范本
- 2025-2030人造板市场发展分析及行业投资战略研究报告
- 返还工伤款项协议书
- 2020-2025年中国智慧仓储行业市场调查研究及投资战略咨询报告
- 什么是个好医护人员的职业素养
- 教育行业服务意识培训
- T-CRHA 085-2024 成人膀胱冲洗并发症护理规范
- Module9 Unit2 Wishing You Happiness Every Day(说课稿)-2023-2024学年外研版(三起)英语六年级下册
- 月嫂资格证考试单选题100道及答案
- 粤沪版物理九年级上册第十二章第1节《认识内能》同步练习
- 水土保持方案投标文件技术部分
- GB/T 3324-2024木家具通用技术条件
评论
0/150
提交评论