20120908-串口编程-MSComm使用2-接收Step by Step

基础太弱,看似很简单的程序也很费周折,MFC熟吗?VC++6.0的环境熟吗?MSComm控件熟吗?任何一件小事儿对于初学者来说都不易,问题太过简单就无人可问,网上查找资料太过费时。今天学习串口编程,原本很小的程序,折腾我大半天,记录存档。例子是《Visual C++ 串口通信技术详解》李景峰、杨丽娜、潘恒著,机械工业出版社2010年6月第1版,这本书中的例子。

 

1.打开VC++6.0,NEW,创建一个名为TTYReceiveMSComm的基于MFC的对话框应用程序。

20120908-串口编程-MSComm使用2-接收Step by Step_第1张图片

 

2.选对话框

 

3.注意:一定要勾选ActiveX Controls,因为MSComm就是ActiveX Controls控件,所以一定要支持它,否则出错。如不勾选,在实例化MSComm控件的时候将出来如下的错误,这个问题指向了MFC框架内部,暂时还不会解决。

 

出错:

20120908-串口编程-MSComm使用2-接收Step by Step_第2张图片

 

4.NEXT

20120908-串口编程-MSComm使用2-接收Step by Step_第3张图片

 

5.NEXT

20120908-串口编程-MSComm使用2-接收Step by Step_第4张图片

 

6.NEXT

20120908-串口编程-MSComm使用2-接收Step by Step_第5张图片

 

7.向项目中添加MSComm控件的方法详见《20120904-加载MSComm控件的方法》这篇文章 

8.主界面如下

20120908-串口编程-MSComm使用2-接收Step by Step_第6张图片

 

9.在资源管理标签页内,右键Dialog虚拟文件夹,Insert一个Dialog

20120908-串口编程-MSComm使用2-接收Step by Step_第7张图片

 

10.这个设置串口的界面如下.

 

11.建立控件变量如下

20120908-串口编程-MSComm使用2-接收Step by Step_第8张图片

 

 

12.建立控件变量如下:

20120908-串口编程-MSComm使用2-接收Step by Step_第9张图片

 

13.双击设置串口的IDD_DIALOG1对话框空白处,为该对话框新建一个类

 

14.起名字如下

 

15.在TTYReceiveMSCommDlg.h中引用如下库文件

#include "mscomm.h"
#include "SetupDlg.h"
#include <math.h>


16.在CTTYReceiveMSCommDlg类的实现部分添加如下变量

	CMSComm myComm;
	CSetupDlg mySetupDlg;
	BYTE myCom;
	CString myParity;
	CString myBaudRate;


 17.主对话框建立的时候,实例化一个MSComm控件,添加OnCreate()函数

20120908-串口编程-MSComm使用2-接收Step by Step_第10张图片

 

int CTTYReceiveMSCommDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	DWORD style=WS_VISIBLE|WS_CHILD;
	if (!myComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1))
	{
		AfxMessageBox("创建MSComm控件失败!");
		m_Opencom.EnableWindow(false);
		m_Closecom.EnableWindow(false);
		m_Setupcom.EnableWindow(false);
		return -1;
	}
	m_Para="COM1,9600,N,8,1";
	
	return 0;
}


 

18.添加Setup()函数

20120908-串口编程-MSComm使用2-接收Step by Step_第11张图片

 

void CTTYReceiveMSCommDlg::OnSetup() 
{
	CString strStatus,strTemp;
	double dblBaud;
	if(mySetupDlg.DoModal()==IDOK)
	{
		myCom=mySetupDlg.m_Com+1;
		dblBaud=pow(2,(double)mySetupDlg.m_BaudRate);
		dblBaud=19200/dblBaud;
		strStatus.Format("%.0f",dblBaud);
		myBaudRate=strStatus;
		
		switch(mySetupDlg.m_Parity)
		{
		case 0:
			{
				myParity="N";
				break;
			}
		case 1:
			{
				myParity="O";
				break;
			}
		case 2:
			{
				myParity="E";
				break;
			}
		}
		strStatus="COM";
		strTemp.Format("%d",myCom);
		strStatus+=strTemp;
		strStatus+=",";
		strStatus+=myBaudRate;
		strStatus+=",";
		strStatus+=myParity;
		strStatus+=",8,1";
		m_Para=strStatus;
		UpdateData(false);
	}	
}


19.添加opencom函数

20120908-串口编程-MSComm使用2-接收Step by Step_第12张图片

 

void CTTYReceiveMSCommDlg::OnOpencom() 
{	
	//以下的初始化只是一个例子,根据实际程序要求的不同,
	//初始化代码可能与此有差别。斜体字代码是必须的。
	CString strPara;                          //串口参数
	myComm.SetCommPort(myCom);                //指定串口号myCom
	strPara=myBaudRate;
	strPara+=",";
	strPara+=myParity;
	strPara+=",8,1";
	myComm.SetSettings(strPara);             //通信参数设置
	myComm.SetInBufferSize(1024);            //指定接收缓冲区大小
	myComm.SetInBufferCount(0);              //清空接收缓冲区
	myComm.SetInputMode(1);                  //设置数据获取方式
	myComm.SetInputLen(0);                   //设置每次读取长度
	myComm.SetRThreshold(1);                 //设置接收OnComm事件门限值
	myComm.SetPortOpen(1);                   //打开串口
	m_Opencom.EnableWindow(false);           //使“打开串口”按钮无效
	m_Closecom.EnableWindow(true);           //使“关闭串口”按钮生效
	m_Setupcom.EnableWindow(false);          //使“设置”按钮无效
	m_Exit.EnableWindow(false);              //使“退出”按钮无效
	AfxMessageBox("串口打开成功!");	
}


 

20.添加关闭串口

20120908-串口编程-MSComm使用2-接收Step by Step_第13张图片

 

void CTTYReceiveMSCommDlg::OnClosecom() 
{
	myComm.SetPortOpen(0);
	AfxMessageBox("串口关闭成功!");
	m_Opencom.EnableWindow(true);
	m_Closecom.EnableWindow(false);
	m_Setupcom.EnableWindow(true);
	m_Exit.EnableWindow(true);
}

 

21.退出函数

void CTTYReceiveMSCommDlg::OnExit() 
{
	this->EndDialog(IDOK); 
}


 

22.添加接收响应函数

20120908-串口编程-MSComm使用2-接收Step by Step_第14张图片

 

void CTTYReceiveMSCommDlg::OnOnCommMscomm1() 
{
	VARIANT input1;
	BYTE rxdata[2048];
	long len1,k;
	COleSafeArray safearray1;
	CString strDis;
	switch(myComm.GetCommEvent())
	{
	case 2:
		//收到 RThreshold 个字符
		//添加接收处理代码
		input1=myComm.GetInput();
		//将VARAIANT变量赋值给COleSafeArray类的实例
		safearray1=input1;     
		//使用COleSafeArray类的成员函数获取数据长度
		len1=safearray1.GetOneDimSize();
		for(k=0;k<len1;k++)
			//使用COleSafeArray类的成员函数将数据写入数组
			safearray1.GetElement(&k,rxdata+k);
		
		for(k=0;k<1;k++)
		{
			if(rxdata[k]==13)
			{
				m_Edit1.SetSel(1000000,1000000);
				m_Edit1.ReplaceSel("\15\12");
				UpdateData(false);
			}
			else
			{
				if(rxdata[k]<=126 && rxdata[k]>=32)
				{
					strDis+=rxdata[k];
					m_Edit1.SetSel(1000000,1000000);
					m_Edit1.ReplaceSel(strDis);
					strDis="";
					UpdateData(false);
				}
			}
		}
	}	
}


 ************************************************************************************************

20120908-串口编程-MSComm使用2-接收Step by Step_第15张图片

20120908-串口编程-MSComm使用2-接收Step by Step_第16张图片

 ************************************************************************************************

 代码上传自我的资源中。

此刻起,再不忽视任何一件小事,谨记!

2012.09.08 于家中

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(20120908-串口编程-MSComm使用2-接收Step by Step)