VC MFC 串口通信(多线程)
来源:互联网 发布:java实现迭代器 编辑:程序博客网 时间:2024/06/05 22:48
VC MFC 串口通信(多线程)
现在一般用VC写串口通信,大多数人会采取下面的三种方式:
一.直接利用VC 里面的MSComm类进行编程。
二.网上也有一个比较好的类,大多数人也喜欢采用SerialPort(此类其实也比较好用)
三.应用API函数进行串口编程。
以上三种方式编程,我都用过的。。。(当然都不是很深入)。其实前两种用起来比较简单一点。就是对串口初始化,在调用MSComm(SerialPort)的函数就可以了。我只是简单的看过上面两个类的定义,其中也有线程的使用。(但是在我使用的时候,我是通过串口接收一副图像,但有时候界面会出现卡死的情况,到此论坛上求助,有人告诉我要创建一个线程,,,这里我到现在都不是很了解,因为我觉得本来就是一个线程吧! 为什么还要创建了。。)于是就学应用API函数进行编程了。
API 函数:API(Application Programming Interface,应用编程接口)其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用程序的命令(只要是在windows环境下编程都可以调用API函数)
利用API函数进行串口编程的步骤:
(1)打开串口:CreatFile()函数
m_hcom=CreateFile("COM1",//COM1口GENERIC_READ|GENERIC_WRITE, //允许读和写0, //独占方式NULL,OPEN_EXISTING, //打开FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式NULL );创建一个关于串口的句柄
(2)创建串口通信事件:CreatEvent()函数
这里涉及到了一个重要的结构体OVERLAPPED:OVERLAPPED是一个包含了用于异步输入输出的信息的结构体,在这个结构体中最重要的一个成员为hEvent,线程利用CreatEvent函数为hEvent创建一个手工重置事,hEvent将作为线程的同步对象使用,初始化的hEvent为有信号的,当读写事件完成操作之后,hEvent会变为有信号。对这一结构,请看这里http://blog.csdn.net/pofenglangguayunfan/article/month/2013/10。
(3)串口的初始化,设置串口参数
/********************输入缓冲区和输出缓冲区的大小***********/ SetupComm(m_hcom,1024,1024);/*********************超时结构(读一次缓冲区就返回)****************************/ COMMTIMEOUTS TimeOuts;TimeOuts.ReadIntervalTimeout=MAXDWORD;//两个字节之间的间隔时间TimeOuts.ReadTotalTimeoutMultiplier=0;//读时间系数TimeOuts.ReadTotalTimeoutConstant=0;//读时间常数TimeOuts.WriteTotalTimeoutMultiplier=100;//设定写超时TimeOuts.WriteTotalTimeoutConstant=500;SetCommTimeouts(m_hcom,&TimeOuts); /******************串口参数的配置*******************/DCB dcb;GetCommState(m_hcom,&dcb);//获得参数dcb.BaudRate=4800;dcb.ByteSize=8;//每个字节8位dcb.Parity=NOPARITY;//无奇偶检验dcb.StopBits=ONESTOPBIT;//两个停止位 SetCommState(m_hcom,&dcb);(4)建立读数据的线程:
一般写数据我们是可以控制的,但读数据的时候,我们不知道数据什么时候会到,所以要建立一个专门的线程,其中用到的函数有:WaitCommEvent,ClearCommError,WaitForSingleObject,ReadFile
OVERLAPPED os;//异状态步输入/输出的 COMSTAT comStat;//通信设备控制块os.hEvent=NULL;os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);os.Offset=0;os.OffsetHigh=0;m_osRead.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL); char czReceiveBuffer[100];DWORD dErrInformation;memset(czReceiveBuffer,0,sizeof(czReceiveBuffer));SetCommMask(m_hcom, EV_RXCHAR);///*if(os.hEvent=NULL){AfxMessageBox("无法创建事件对象!");return (UINT)-1;}*//****************** 在通信之前清除掉错误信息**************/if(m_hcom!=NULL){ClearCommError(m_hcom,&dErrInformation,&comStat);}while(TRUE){ DWORD wEven; INT bResult=WaitCommEvent(m_hcom,&wEven,&os); //DWORD BytesRead;if(!bResult) { switch(GetLastError()) { case ERROR_IO_PENDING: break; case 87: break; default: break; } } else { ClearCommError(m_hcom,&dErrInformation,&comStat); if(comStat.cbInQue==0) { continue; } } INT nEvent=WaitForSingleObject(os.hEvent,INFINITE); if(nEvent==WAIT_OBJECT_0) { DWORD CommEvent=0;GetCommMask(m_hcom,&CommEvent);if(CommEvent&EV_RXCHAR==EV_RXCHAR)//输入缓冲区接收到新字符{ BOOL bread=TRUE; BOOL bresult=TRUE; DWORD deError=0; DWORD BytesRead=0; ///////////////////// COMSTAT comstat; for(;;) { DWORD dRBufferSize=100; INT bResult=ClearCommError(m_hcom,&deError,&comstat);//成功返回值非0 if(comstat.cbInQue==0) { break; } if(bread) { strRec=""; bresult=ReadFile(m_hcom,czReceiveBuffer,100,&dRBufferSize,&m_osRead); if(!bresult) { switch(deError=GetLastError()){case ERROR_IO_PENDING:{bread=FALSE;break;}default:{break;}} } else { bread=TRUE; } } if(!bread) { bread=TRUE;bresult=GetOverlappedResult(m_hcom,&os, &BytesRead, TRUE); if(!bresult){} } PurgeComm(m_hcom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); for(DWORD k=0;k<dRBufferSize;k++) { strRec+=czReceiveBuffer[k]; } ::PostMessage(m_hVieWnd,WM_RECEDATA,(unsigned int)czReceiveBuffer,dRBufferSize); }} }if(nEvent!=WAIT_OBJECT_0){GetLastError();}}return TRUE;(5)写数据:用WriteFile()函数
OVERLAPPED m_osWriter;memset(&m_osWriter,0,sizeof(OVERLAPPED));m_osWriter.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);UpdateData(true);//m_strSend += "/n";COMSTAT ComStat;DWORD dwErrorFlags;BOOL bWriterStat;DWORD dwBytesWrite=0;ClearCommError(m_hcom,&dwErrorFlags,&ComStat);bWriterStat = WriteFile(m_hcom,m_strSend,m_strSend.GetLength(),&dwBytesWrite,&m_osWriter);if(!bWriterStat){ if(GetLastError()==ERROR_IO_PENDING) { WaitForSingleObject(m_osWriter.hEvent,1000); }}(6)
终止线程CloseHandle();
- VC MFC 串口通信(多线程)
- 多线程串口通信 MFC CSerialPort
- MFC VC++多线程间通信
- 基于VC的多线程串口通信程序设计
- 异步串口通信 VC++(VC在线)
- VC++6.0下基于MFC的串口通信助手实现
- 多线程技术在VC++串口通信程序中的应用研究
- 多线程技术在VC++串口通信程序中的应用研究
- 多线程技术在VC++串口通信程序中的应用研究
- 多线程技术在VC++串口通信程序中的应用
- 多线程技术在VC++串口通信程序中的应用研究
- 多线程技术在VC++串口通信程序中的应用研究
- 多线程技术在VC++串口通信程序中的应用研究
- 多线程技术在VC++串口通信程序中的应用研究
- 多线程在VC++串口通信程序中的应用
- VC++(MFC)多线程编程
- 串口通信(MFC)
- 串口通信(MFC)
- Mysql开启远程连接方法
- J2EE环境搭建(三)配置Tomcat 7.0的局部数据源
- TCP协议的流量控制、拥塞控制和差错控制
- wiki-1040统计单词个数
- 学习网站整理
- VC MFC 串口通信(多线程)
- 关于字符串的内存分配问题
- Mongo数据操作
- 如果需要详细题解的进来
- AppStore应用发布流程
- jQuery Ajax请求-jQuery.getScript(url, [callback])
- 解决 Win7 64位安装Oracle11g时出现的 [INS-20802] Oracle Net Configuration Assistant failed 错误
- C#计算时间间隔的方法小结
- Ubuntu的shell之bash和dash