




免费预览已结束,剩余3页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
用Visual C+编制串行通信程序摘要: 本文介绍了在Win32环境下用Visual C+的MFC实现串行通信方法,用类实现多线程编程,较好地将32位串口通信的API函数封装在一个类中实现串行通信,并给出示例程序。关键词:串行通信多线程 Visual C+ MFC随着计算机应用深入,经常需要通过计算机RS-232串口与外部设备通信,采集如温度、压力、重量等模拟数据,或发出控制信息,用Visual C+编制串行通信程序可有三种方法:1、采用Microsoft Win32应用程序编程接口(API)所提供串行通信函数,用SDK思路编写。2、用ActiveX通讯控件开发串行通信程序。3、用C+的MFC思路,将Win32串口通信的API函数封装在一个类中实现串行通信。前两种方法己有不少刊物已作过介绍,方法各有利弊,而第三种方法较为繁琐,不仅要了解Win32位串行通信的API函数,还要掌握多线程编程,但控制灵活,既涉及到底层编程、纠错能力强,又有C+风格,为专业C+开发人员所采用。本文就在Win32环境下串行通信、多线程编程概念作简单叙述,并给出相应的示例程序,以供参考。一、串口通信1串口通信步骤 :一般编制串行通信程序分四个部分:A 打开串行端口:打开通信资源,设置通信参数、设置通信事件、创建读、写事件、进入等待串口消息循环。B 读取串行端口信息,当串口发生EV_RXCHAR(接收到字符并放入了输入缓冲区)消息后读取串口、数据传输错误处理、字符串处理如回车符、空格并相应转化成数据,如果模拟量还要进行数据检验等功能。C 写串行端口信息:将要发送的信息写入串口,相应进行错误处理。D 断开串行端口连接:关闭事件,清除通信事件,丢弃通信资源并关闭。2 串口通信函数在Win32环境下,由于Windows禁止应用程序直接和硬件打交道,所以程序员只能用Win32API提供的串行通信函数与串行端口打交道,主要函数有:打开、关闭通信资源CreateFile();CloseHandle( );设置通信资源SetCommState(()等待串口事件WaitCommEvent()创建、关闭事件对象 CreateEvent();CloseHandle()串口读写ReadFile(),WriteFile()以上函数具体如何使用见示例或联机帮助。在Windows3.1-16位通信函数有一个WMCOMMNOTIFY消息,每当发生一个串行端口事件,通信设备驱动器就发送此消息,以便程序读、写串信端口,在Win32中已被取消,而串行端口事件(特别接收串口数据)与外部设备有关,计算机要保证及时接收数据又不使主程序暂停,就要引入多线程编程。3 多线程现实生活中,许多事情都时同时进行的,在我们设计应用程序时,也就常常需要采用并行编程机制多线程,在本示例中,主线程负责创建子线程、向串口发送信息,子线程等待串口EV_RXCHAR(收到字符放入缓冲区)事件,读取缓冲区字符并显示。一般MFC将线程分两类:用户界面线程和工作者线程,工作者线程没有消息循环,只是一般函数,本示例中采用是用户界面线程,其实现方法为:4从CWinThread派生新的子类。必须用宏DECLARE_DYNCREATE()和IMPLEMENT_DYNCREATE声明和实现CwinThread5 在CwinThread派生类覆盖以下函数。. InitInstance:执行线程实例的初始化。. ExitInstance:在线程终止时执行清理工作。. Run:控制线程的函数,包含消息循环。.OnIdle:执行线程的空闭处理。a)调用全局函数AfxBeginThread启动用户界面线程。此时,采用以下原型:CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );其中,参数pThreadClass为从CWinThread派生类对象的RUNTIME_CLASS宏调用;nPriority用于指定线程优先级(可选)可以调用API函数SetThreadPriority设置优先级;nStackSize用于指定线程的堆栈大小;dwCreateFlags为控制线程创建的附加标记,如果为CREATE_SUSPENDED,则创建线程为挂起状态,必须调用成员函数ResumeThread恢复;lpSecurityAttrs用于指定安全属性。要保证线程之间数据正常传输,还要涉及线程间通信、线程间同步等内容,有兴趣读者可参阅有关资料。6 串行通信程序流程左边是主线程,右边为子线程。实线框为视类函数,虚线为通信类函数响应菜单“打开串口”启动用户界面线程(挂起状态)打开通信资源,串口参数设置构造通信类初始化启动子线程等待串口事件显示接收的数据读串口数据EV_RXCHAR连接标记控制线程函数RUN创建读、写串口事件断开关闭事件子线程结束子线程开始运行断开线程终止(获取退出码)连接标记“断开”向串口发送空事件关闭串口响应菜单“关闭串口”响应菜单“发送数据”写数据到串口7 示例程序编制a)建工程文件ComTest打开VisualC+5.0(6.0),利用MFC AppWizard新建ComTest工程文件,选中单文档,其余为缺省值。并在视类建立“串口测试”下拉菜单项,包括“打开串口”、“关闭串口”和“写串口测试”三项菜单。b)建立串口通讯类选择“Insert”菜单项中“New Class”弹出“建新类”对话框,输入类名为“CcomCUnic”选中CwinThread为基类,并相应编写如下函数/线程循环主函数,当线程被启动执行int CcomCUnic:Run() DWORD dwEvtMask ;int nLength ;BYTE abIn 80 ;/创建事件句柄osRead.hEvent= CreateEvent( NULL, TRUE, FALSE, NULL ) ;if (osRead.hEvent = NULL)AfxMessageBox( NULL, 建立事件失败!) ;return ( FALSE ) ;/设置串口 “收到字符放入缓冲区”事件if (!SetCommMask(COMFile, EV_RXCHAR ) return ( FALSE )/bCONNECTED串口连接标记while ( bCONNECTED )dwEvtMask = 0 ;/等待串口事件WaitCommEvent( COMFile, &dwEvtMask, NULL );if (dwEvtMask & EV_RXCHAR) = EV_RXCHAR)do/读取串口字符nLength=ReadCommBlock( (LPSTR)abIn );/输出接收字符if(nLength0)pView-OutChar(LPSTR)abIn,nLength);while ( nLength 0 ) ;/子线程结束CloseHandle( osRead.hEvent ) ;return CWinThread:Run();/打开串行端口,设置端口参数,被视类“打开串口”调用BOOL CcomCUnic:OpenConnection( ) BYTE bSet;DCB dcb ; BOOL fRetVal ;COMMTIMEOUTS CommTimeOuts;if (COMFile=CreateFile( COM1, GENERIC_READ | GENERIC_WRITE,/可读、可写0, / 不共享NULL, / 无安全描OPEN_EXISTING,/打开已存在文件FILE_ATTRIBUTE_NORMAL |FILE_FLAG_OVERLAPPED, / 文件属性NULL ) = (HANDLE) -1 )return ( FALSE ) ;/ 指定监视事件_收到字符放入缓冲区SetCommMask( COMFile, EV_RXCHAR ) ;/ 设置缓冲区SetupComm( COMFile,4096,4096) ;/ 刷清缓冲区PurgeComm( COMFile, PURGE_TXABORT | PURGE_RXABORT |PURGE_TXCLEAR | PURGE_RXCLEAR ) ;meOuts.ReadIntervalTimeout = 0xFFFFFFFF ;CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;CommTimeOuts.WriteTotalTimeoutMultiplier = 2*CBR_9600/9600 ;CommTimeOuts.WriteTotalTimeoutConstant = 0 ;/给定串口读与操作限时SetCommTimeouts( COMFile, &CommTimeOuts ) ;/设置串口参数:波特率=9600;停止位 1个;无校验;8位dcb.DCBlength = sizeof( DCB ) ;GetCommState( COMFile, &dcb ) ;dcb.BaudRate =CBR_9600;dcb.StopBits =ONESTOPBIT;dcb.Parity = NOPARITY;dcb.ByteSize=8;dcb.fBinary=TRUE;dcb.fOutxDsrFlow = 0 ;dcb.fDtrControl = DTR_CONTROL_ENABLE ;dcb.fOutxCtsFlow = 0 ;dcb.fRtsControl = RTS_CONTROL_ENABLE ;dcb.fInX = dcb.fOutX = 1 ;dcb.XonChar = ASCII_XON ;dcb.XoffChar = ASCII_XOFF ;dcb.XonLim = 100 ;dcb.XoffLim = 100 ;dcb.fBinary = TRUE ;dcb.fParity = TRUE ;/根据设备控制块配置通信设备fRetVal = SetCommState( COMFile, &dcb ) ;if(!fRetVal) return FALSE; /指定串口执行扩展功能EscapeCommFunction( COMFile, SETDTR ) ;return TRUE ;/关闭串行端口BOOL CcomCUnic:CloseConnection()bCONNECTED = FALSE ;/禁止串行端口所有事件SetCommMask( COMFile, 0 ) ;/清除数据终端就绪信号EscapeCommFunction( COMFile, CLRDTR ) ;/丢弃通信资源的输出或输入缓冲区字符并终止在通信资源上挂起的读、写操/场作PurgeComm( COMFile, PURGE_TXABORT | PURGE_RXABORT |PURGE_TXCLEAR | PURGE_RXCLEAR ) ;CloseHandle( COMFile );return TRUE;/读串行端口数据-被RUN调用int CcomCUnic:ReadCommBlock(LPSTR lpszBlock)DWORD dwErrorFlags;COMSTAT ComStat ;DWORD dwLength;ClearCommError( COMFile, &dwErrorFlags, &ComStat ) ;dwLength = ComStat.cbInQue;if (dwLength 0)ReadFile( COMFile, lpszBlock, dwLength, &dwLength, &osRead )return ( dwLength ) ;/写数据到串行端口-被视类“发送数据”调用BOOL CcomCUnic:WriteTTYBlock(LPSTR lpBlock, int nLength )DWORD dwLength;WriteFile( COMFile, lpBlock,nLength, &dwLength, &osRead );return true;a) 编写视类“打开串口”、“关闭串口”和“发送数据”菜单响应函数;/打开串口函数void CComTestView:OnOpenCom() /创建等待线程,因要设置串行端口参数m_pCcomCUnic=(CcomCUnic*)AfxBeginThread(RUNTIME_CLASS(CcomCUnic), THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);if(m_pCcomCUnic=NULL)m_bLineCom=FALSE;else/保存视类指针,显示读取串口的字符用m_pCcomCUnic-pView=this;/打开串口准备读串口m_bLineCom=m_pCcomCUnic-OpenConnection( );/串口初始化,读取串口数据m_pCcomCUnic-bCONNECTED=TRUE; /线程开始执行m_pCcomCUnic-ResumeThread();/发送串口通信DTR信号/EscapeCommFunction(m_pCcomCUnic-COMFile, SETDTR ) ;/关闭串口函数void CComTestView:OnCloseCom() DWORDdwStatus;VERIFY(:GetExitCodeThread(m_pCcomCUnic-m_hThread, &dwStatus);m_pCcomCUnic-CloseConnection();/输出字符“Test OK”到
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【正版授权】 ISO 30414:2025 EN Human resource management - Requirements and recommendations for human capital reporting and disclosure
- 去年初二数学试卷
- 围网灯光施工方案(3篇)
- 亲子小程序活动策划方案(3篇)
- 防冻水管施工方案(3篇)
- 沃尔沃卡车施工方案(3篇)
- 卫浴知识考试题库及答案
- 山东应急考试题库及答案
- 农村现代农业技术服务外包合同
- 企业员工薪酬福利外包服务合同书
- 2025年新版节能减排生态环保知识竞赛考试题库及答案
- 加油站资金安全知识培训课件
- 2025年专职网格员笔试题及答案
- 2025年重庆交安考试题库及答案
- 高中数学《新课程标准》考试试题及答案
- 2025年岗前安全培训试题及答案
- 2025年甘肃兰州市事业单位招考笔试《公共基础知识》题库(共50题)及答案
- 地铁站基坑施工监测方案
- 2025-2026年秋季学期教研工作计划及工作行事历
- 物业外包方管理课件
- 卫星运行教学课件
评论
0/150
提交评论