vs2013 MFC 串口上位机

一:首先我用的是http://jingyan.baidu.com/article/09ea3ede3b2496c0afde3944.html百度经验里面给的VS2013,是有串口控件(Microsoft communication control)

二:参照这个百度经验http://jingyan.baidu.com/article/8ebacdf0c96b5549f65cd5fa.html新建一个MFC基于对话框的工程,取名为MFC_COMMN,然后主对话框右键,有个添加Active控件,

点中后往里面的列表找到Microsoft communication control这个控件,

添加到对话框中,控件的样子是一个电话,如果没有的话得去百度寻找答案了。。

三: http://wenku.baidu.com/link?url=7MyT1jpd6AUtAcQ6wPKZAlnDOyplxIv0lX2hGUOY_YZZWnzsCxY-e3RLeDo7EvsrHzpQTpiPfGrHrEm3NQrlDfsZ4lP7Gj8c52iqGku2qPe

我们用上面这篇文档来讲VC++6.0的代码移植到VS2013中,主要的改动为串口类的成员函数的名字与VC++6.0的有些不同,比如SetCommport变为了put_CommPort,之类的。。所以通过查看CMScomm1的类定义可以做相应的修改。。

四:切换工作窗口为解决方案资源管理器,打开MFC_COMMNDlg.h头文件


在CMFC_COMMNDlg类中添加代码:

<pre name="code" class="cpp">int gllen;//定义整型标量gllen,用于记录接收数据的个数
	CString strRXDdata; //编辑框显示的文本,记录历次转换值


 
 
 
 

如图所示:


五:VC++6.0的代码到VS2013要解决编码问题,将独热码修改为多字节编码:菜单栏中的项目->MFC_COMMN属性->配置属性->常规->字符集->选择多字节字符集。

但是改完后编译会报错,因为我找了百度发现是因为:http://jingyan.baidu.com/article/6181c3e06ab30f152ff1534d.html

然后我们得去http://www.microsoft.com/zh-cn/download/details.aspx?id=40770下载这个插件安装,上面百度经验的解释为:最后啰嗦一句,出现这样的问题,微软的解释是:用于多字节字符编码 (MBCS) 的 MFC 库 (DLL) 不再包含于 Visual Studio 中,但是可用作插件,您可以在任何装有 Visual Studio Professional、Visual Studio Premium 或 Visual Studio Ultimate 的计算机上下载和安装。


六:切换到对话框,添加编辑框,ID为IDC_EDIT2          两个按钮,ID分别为IDOK和ID_serial_state_switch   然后往IDOK按钮的事件处理函数中添加代码

// TODO:  在此添加控件通知处理程序代码 
	CByteArray m_Array; //定义字节数组
	m_Array.RemoveAll(); //字节数组清空
	m_Array.SetSize(1); //设定维数为1
	m_Array.SetAt(0,0x15); //给m_array[0]赋值发送的字节为0x15
	m_comm1.put_Output(COleVariant(m_Array));//由于SetOutput函数的参数为VARIANT型,必须强制转换后才能发送
			
如图所示

往另一个按钮中添加代码:

<pre name="code" class="cpp">void CMFC_COMMNDlg::OnBnClickedserialstateswitch()
{
	// TODO:  在此添加控件通知处理程序代码

	if (!m_comm1.get_PortOpen())//判断串口是否已经打开
	{
		m_comm1.put_PortOpen(TRUE); //如果串口是关闭的,则打开串口

		GetDlgItem(ID_serial_state_switch)->SetWindowText("关闭串口");
	}
	else
	{
		m_comm1.put_PortOpen(FALSE); //如果已经打开串口,则关闭串口
		GetDlgItem(ID_serial_state_switch)->SetWindowText("打开串口");
	}
}


 
 

下面是往OnInitDialog中添加代码。。。

//**************添加的串口代码
	gllen = 0; //记录转换次数全局变量清零
	if (!m_comm1.get_PortOpen())//判断串口是否已经打开
	{
		
		
		m_comm1.put_CommPort(3); //选择串口号3
		m_comm1.put_PortOpen(TRUE); //打开串口
		m_comm1.put_RThreshold(2); //收到两个字节引发OnComm事件
		m_comm1.put_InputMode(1);//输入模式选为二进制
		m_comm1.put_Settings("9600,n,8,1"); //设置串口参数,波特率9600,无奇偶校验,1位停止位,8位数据位
		MessageBox("串口初始化完毕", "提示"); //提示串口成功初始化
	}
	else  MessageBox("串口被占用", "提示"); //如果已经打开串口,消息框提醒
	
	GetDlgItem(ID_serial_state_switch)->SetWindowText("关闭串口");//按钮显示状态改变
	//*********************************添加的串口代码
如图所示:

最后往串口响应函数OnCommMscomm1中添加代码

	// TODO:  在此处添加消息处理程序代码
	VARIANT variant1;//定义VARIANT型变量,用于存放接收到的数据
	COleSafeArray safearray;//定义safearray型变量
	long  k;//定义长整型变量len,k
	long len;
	BYTE rxdata[2048];//定义BYTE型数组
	CString stremp1, stremp2;//定义两个字符串
	if (m_comm1.get_CommEvent() == 2) //判断引起OnComm时间的原因,接收事件
	{//如果是接收到特定个字节数,则读取接收到的数据
		variant1 = m_comm1.get_Input();//把接收到的数据存放到VARIANT型变量里
		safearray = variant1;//VARIANT型变量转换为ColeSafeArray型变量
		len = safearray.GetOneDimSize();
		
		
		for (k = 0; k<len; k++)
		{
			safearray.GetElement(&k, rxdata + k); //得到接接收到的数据放到BYTE型数组rxdata里
		}
		for (k = 0; k<len; k++)
		{
			BYTE bt = (*(unsigned char*)(rxdata + k)); //读取AD转换的高字节
			if ((k % 2) == 0)
			if ((k + 1)<len)
			{
				gllen++;//全局的变量,对接收到的转换结果的个数进行计算
				stremp2.Format("第%d次转换结果:", gllen);//显示第几次转换
				int temp = bt * 16 + ((*(unsigned char *)(rxdata + k + 1)) ); //高低字节合并成实际的转换结果,注意转换结果是左对齐
				//AllocConsole();//注意检查返回值
				//_cprintf("rxdata0=%d\n rxdata1=%d\n temp=%d\n", rxdata[0], rxdata[1],temp);
				//_getch();
				stremp1.Format("%2.2f", (2.56*temp / 1024));//计算成实际电压值
				SetDlgItemText(IDC_STATIC, ("当前电压值为: " + stremp1 + " V")); //更新静态文本控件
				
				strRXDdata += stremp2;//把新的数据放到全局的字符串里  
				strRXDdata += stremp1;
				strRXDdata += " V\r\n";//字符串加单位V后换行
			}
		}
	}


	SetDlgItemText(IDC_EDIT2, strRXDdata);//更新文本控件的显示
	


	
	

七:单片机测试代码:

<pre name="code" class="cpp"><pre name="code" class="cpp">/*********************************************************************************
* 【编写时间】: 2011.07.07
* 【作    者】: 雁翎电子
* 【版    本】: V1.0
* 【网    站】: http://ylelectronic.taobao.com/ 
* 【Q      Q】: 348439350
* 【声    明】: 此程序仅用于学习与参考,引用请注明版权和作者信息!
* 【函数功能】: 串口中断程序实验——通过单片机向电脑发送数据,同时电脑将收到的数据发出			   			            			    
**********************************************************************************/


/*预处理命令*/
#include <reg52.h> 		  //包含单片机寄存器的头文件
#define uchar unsigned char
#define uint unsigned int
uchar num,a;

/*
********************************************************************************
** 函数名称 : main(void)
** 函数功能 : 主函数
********************************************************************************
*/
void main()
{
	TMOD=0x20;		   //用定时器设置串口波特率	   9600 
	TH1=0xfd;
	TL1=0xfd;
	TR1=1;
	REN=1;          //串口初始化
	SM0=0;
	SM1=1;
	EA=1;           //开启总中断
	ES=1;
	while(1)
	{
		if(num==1)    //判断是否有串口数据的传送
		{
			ES=0;
			num=0;
			SBUF=a;			 //发送数据a到SBUF,即将单片机的数据发送到计算机
			while(!TI);
			TI=0;
			SBUF=0xff;	//发送数据0xff到上位机
				while(!TI);
			TI=0;
			ES=1;
		}
	}	
}
void ser() interrupt 4
{
	RI=0;
	P2=SBUF;			//接收数据SBUF,即将计算机的数据接收。
	a=SBUF;
	num=1;
}


 
 
 
 

八:安装好单片机的USB驱动,然后再设备管理器显示的是COM3,如果是其他的COM号码,那么你就修改

	m_comm1.put_CommPort(3); //选择串口号3

里面的参数。

九:运行软件:


为什么是1.48呢,因为发送了0x15,然后 返回0x15和0xff    然后0x15=21   0xff=255    21乘以16加上255等于591,然后591*2.56/1024=1.4775

十:调试:声明#include <conio.h>

在定义temp的代码下面添加

AllocConsole();//注意检查返回值
				_cprintf("rxdata0=%d\n rxdata1=%d\n temp=%d\n", rxdata[0], rxdata[1],temp);
				_getch();
就可以输出接收到的数据和temp的值了

如图


运行程序,点击开始转换,就可以有:






你可能感兴趣的:(mfc,mfc,串口,Visual,Studio,上位机)