VS2010 基于MFC 的串口通信上位机总结

VS2010 基于MFC 串口通信上位机,实现串口发送、接收数据及接收数据保存。
提示:不清楚的函数可在MSDN 内查询

  1. 打开VS2010 创建 MFC应用程序,选择基于对话框类 ,勾选最大化框、最小化框后 选择下一步完成。

  2. 将对话框上原有的控件删除,添加所需的控件。
    发送部分:Radio Button、Combo Box
    接收部分:Edit Control
    选择串口、波特率:Combo Box
    按键:打开串口、发送数据、清除数据、保存数据、退出
    图标显示:指示串口打开、关闭状态
    Activex 串口控件:Microsoft Communications Control,Version 6.0
    提示:VS2010 内找不到此Activex 控件的解决方法 :https://blog.csdn.net/madao1234/article/details/82047796

3.为各控件添加控制程序
① 打开串口按钮 ,显示指示图标
提示:双击打开按钮 会直接跳转到 void C串口Dlg::OnBnClickedButtonOpen() 函数

void C串口Dlg::OnBnClickedButtonOpen()
{
	// TODO: 在此添加控件通知处理程序代码
	CString str,str1,n; //定义3个CString变量
	GetDlgItemText(IDC_BUTTON_OPEN,str); //获取打开串口按键的Caption,IDC_BUTTON_OPEN:打开串口按键的ID
	CWnd *h1;  //定义句柄类的指针
	h1 = GetDlgItem(IDC_BUTTON_OPEN); // h1 赋为 指向IDC_BUTTON_OPEN 按键的句柄

	if(!m_mscom.get_PortOpen()) //如果串口未打开
	{
		//m_comb3:波特率选择组合框的 成员变量
		m_comb3.GetLBText(m_comb3.GetCurSel(),str1); //取得波特率口当前的选择值,存放在str1里 
		
		str1 = str1 + _T(",n,8,1"); 
		m_mscom.put_Settings(str1);// 设置波特率、无校验,8数据位,1个停止位

		m_mscom.put_InBufferSize(1024); //接收缓冲区大小设置
		m_mscom.put_OutBufferSize(1024);//发送缓冲区大小设置

		m_mscom.put_CommPort((m_comb1.GetCurSel()+1)); //选择串口,m_comb1:串口选择组合框的 成员变量
		m_mscom.put_InputMode(1); //设置输入方式 二进制方式
		m_mscom.put_InputLen(0);// 设置当前接收区数据长度为0,表示全部读取
		m_mscom.put_RThreshold(2); // 缓冲区有2个字符引发OnComm事件

		m_mscom.put_PortOpen(true); //打开串口
		m_mscom.get_Input(); //先预读缓冲区以清除残留数据

		if(m_mscom.get_PortOpen()) //如果串口打开
		{
			str = _T("关闭串口"); // str打开按钮的Caption 赋为 “关闭串口”
			UpdateData(TRUE);//用于将屏幕上控件中的数据交换到变量中
			h1->SetWindowText(str); //打开串口按键 文本将被修改
			m_Icon.SetIcon(m_hIcon_Open); //显示打开图标
		}
	  }
	 else
	  {
		m_mscom.put_PortOpen(false); //关闭串口
		if(str != _T("打开串口"))  
		{
			str = _T("打开串口");
			UpdateData(TRUE);
			h1->SetWindowText(str); 
			m_Icon.SetIcon(m_hIcon_Close); //显示关闭图标
		}
	   }
}

② 串口打开、关闭 图标显示
首先,准备好2个Icon 图标, 在资源视图内右键—>添加资源—>导入 ,选择2个Icon。 导入后自动分配了ID: IDI_ICON1\ IDI_ICON2 .
在BOOL C串口Dlg::OnInitDialog() 内添加如下代码:

//m_hIcon_Open:串口打开图标的HICON 类型的成员变量
//m_hIcon_Close :串口关闭图标的HICON 类型的成员变量
//LoadIcon从与应用程序实例相关联的可执行文件(.EXE)文件中加载指定的图标资源
m_hIcon_Open = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));

m_hIcon_Close = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON2));

m_Icon.SetIcon(m_hIcon_Close); //设置初始显示为关闭图标

③选择串口 与 波特率 的 Combo Box 设置
在BOOL C串口Dlg::OnInitDialog() 内添加如下代码:

// 串口组合框:显示com1~com15
CString str;
for(i=0;i<15;i++) 
{
	str.Format(_T("com %d"),i+1);
	m_comb1.InsertString(i,str);
}
m_comb1.SetCurSel(0); 

//波特率组合框
CString str1[]={_T("4800"),_T("9600"),_T("19200"),_T("38400"),_T("43000"),_T("56000"),_T("57600"),_T("115200")};
for(int i = 0; i<8 ; i++)
{
	int judge_tf=m_comb3.AddString(str1[i]);
	if((judge_tf==CB_ERR)|(judge_tf==CB_ERRSPACE))
		MessageBox(_T("设置波特率错误"));
}
m_comb3.SetCurSel(7);

//运行次数选项框
int i;
CString str2[]={_T("1"),_T("2"),_T("3"),_T("4"),_T("5"),_T("6"),_T("7"),_T("8"),_T("9")};
for(int i = 0; i<9 ; i++)
{
	int judge_times=m_Runtime.AddString(str2[i]);
	if((judge_times==CB_ERR)|(judge_times==CB_ERRSPACE))
		MessageBox(_T("未设置运行次数"));
}
m_Runtime.SetCurSel(0);

④ Radio选择框设置,发送数据按钮
多个Radio Button 将第一个的Group改为True 按照Tab顺序会将其他Radio Button 分为一组,返回值分别为0,1,2 …
双击发送数据按钮,添加控制程序:

void C串口Dlg::OnBnClickedButtonSend()
{
	// TODO: 在此添加控件通知处理程序代码
	CString str,str1,SendData;
	UpdateData(TRUE); //将控件的状态传给其关联的变量
	str.Format(_T("%d"),m_MMSet);  //将 单选按钮的 int变量值强制转换成CString类型

	m_Runtime.GetLBText(m_Runtime.GetCurSel(),str1);//运行次数选择框返回值
	SendData = str + str1; //发送的数据 
	//UpdateData(TRUE);
	m_mscom.put_Output(COleVariant(SendData)); //数据发送

}

⑤清除数据按钮

void C串口Dlg::OnBnClickedButtonClean()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Edit1_Rev1 = _T(""); //给接收编辑框发送空格符
	m_Edit1_Rev2 = _T(""); 
	m_Edit1_Rev3 = _T(""); 
	m_Edit1_Rev4 = _T(""); 
	m_Edit1_Rev5 = _T("");

	UpdateData(FALSE);//将数据在屏幕中对应控件中显示出来
}

⑥ 关闭按钮

void C串口Dlg::OnBnClickedButtonClose()
{
	// TODO: 在此添加控件通知处理程序代码
	if(m_mscom.get_PortOpen())
		m_mscom.put_PortOpen(FALSE);

	CDialogEx::OnCancel();
}

⑦ 串口控件程序:点击Activex 控件,右键 为控件添加处理程序
功能 :多个接收编辑框分别显示接收数据

void C串口Dlg::OnCommMscomm1()
{
	// TODO: 在此处添加消息处理程序代码
	CString strtemp;
	if(m_mscom.get_CommEvent()==2)  //事件值为2 表示接收缓存区内有字符
	{
		BYTE str[2048]={0};
		long len,k;
		COleSafeArray fs;
		int flag,i=0;
		
		VARIANT InputData = m_mscom.get_Input(); //读缓冲区
		fs = InputData;  //Variant类型变量转换成 COleSafeArray型变量
		len = fs.GetOneDimSize(); //得到有效数据长度
		for(k = 0;k < len;k++)
			fs.GetElement(&k,str+k); //转换成BYTE型数组
		for(k = 0;k < len;k++)  //将数组转换为CString型变量
		{
			BYTE bt=*(char*)(str+k); //字符型
			strtemp.Format(_T("%c"),bt); //将字符输入临时变量strtemp
//输出为多个显示框,显示位置标志			
			if(strtemp == 'a') 
			{
				flag = 0;
			}
			else if(strtemp == 'b') 
			{
				flag = 1;
			}
			else if(strtemp == 'c') 
			{
				flag = 2;
			}
			.....
//显示数据写入
			switch(flag)
			{
			case 0:
				m_Edit1_Rev1 = _T(""); //清空显示
				for(k=1;k<len;k++)
				{
					bt=*(char*)(str+k); //字符型
					strtemp.Format(_T("%c"),bt); //将字符输入临时变量strtemp
					m_Edit1_Rev1 += strtemp;
				}
				break;

			case 1:
				m_Edit1_Rev2 = _T(""); 
				for(k=1;k<len;k++)
				{
					bt=*(char*)(str+k); //字符型
					strtemp.Format(_T("%c"),bt); //将字符输入临时变量strtemp
					m_Edit1_Rev2 += strtemp;
				}
				break;

			case 2:
				m_Edit1_Rev3 = _T(""); //清空显示
				for(k=1;k<len;k++)
				{
					bt=*(char*)(str+k); //字符型
					strtemp.Format(_T("%c"),bt); //将字符输入临时变量strtemp
					m_Edit1_Rev3 += strtemp;
				}
				break;
			}
		}
		UpdateData(FALSE); // 更新编辑框内容
	}
}

⑧ 数据保存按键
将数据保存为csv格式

void C串口Dlg::OnBnClickedButtonSave()
{
	// TODO: 在此添加控件通知处理程序代码
	CString str,str1,str2,str3,str4;
	//构建文件保存为对话框,默认扩展名为.csv,初始文件名为空...
	CFileDialog fg(false,_T("*.csv"),NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
		_T("Text File(*.txt)|*.txt|Excel CSV File(*.csv)|*.csv|All Flie(*.*)|*.*||"),NULL);


	str1 = _T("文本,");//文本为行标题,换单元格
	str2 = _T("文本,");
	str3 = _T("文本,");
	str4 = _T("文本,");
	str8 = _T(",文本,文本,文本\n"); // 文本为列标题
	
	if(fg.DoModal()==IDOK) //创建对话框成功
	{
		CString filename = fg.GetPathName(); //文件的完整路径
		CStdioFile mFile(filename,CFile::modeCreate|CFile::modeWrite); //指定文件路径、创建只写模式
		//写入第1个 Radio Button控制的数据

		switch (m_MMSet)
		{ 
		case 0:
			mFile.Write(str1,str1.GetLength());
			GetDlgItemText(IDC_RADIO1,str);  
			mFile.WriteString(str+"\n"); 
			break;
		case 1:
			mFile.Write(str1,str1.GetLength());
			GetDlgItemText(IDC_RADIO2,str); 
			mFile.WriteString(str+"\n");
			break;
		case 2:
			mFile.Write(str1,str1.GetLength());
			GetDlgItemText(IDC_RADIO3,str); 
			mFile.WriteString(str+"\n");
			break;
		default:
			break;
		}
		//写入第2个文本 的数据
		mFile.Write(str2,str2.GetLength());
		GetDlgItemText(IDC_COMBO1,str);
		mFile.WriteString(str+"\n");

		mFile.Write(str8,str8.GetLength()); //写列标题

		//写入接收框1的数据
		
		mFile.Write(str3,str3.GetLength());
		GetDlgItemText(IDC_EDIT1_Rev1,str); //写入接收框数据
		mFile.WriteString(str);//指定一个指向包含空终止文本字符串的缓冲区的指针。
		GetDlgItemText(IDC_EDIT2_Rev1,str);
		mFile.WriteString(",");
		mFile.WriteString(str);
		GetDlgItemText(IDC_EDIT3_Rev1,str);
		mFile.WriteString(",");
		mFile.WriteString(str+"\n");
	
		//写入接收框2的数据
		mFile.Write(str4,str4.GetLength());
		GetDlgItemText(IDC_EDIT1_Rev2,str); 
		mFile.WriteString(str); 
		GetDlgItemText(IDC_EDIT2_Rev2,str);
		mFile.WriteString(",");
		mFile.WriteString(str);
		GetDlgItemText(IDC_EDIT3_Rev2,str);
		mFile.WriteString(",");
		mFile.WriteString(str+"\n");
	}

}

这里写图片描述
使用虚拟串口测试,可以实现 数据发送、接收、保存 。

  • 14
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
VS2017 MFC 是一款常用的软件开发工具,可以用来编写串口上位机程序串口上位机是一种用于与嵌入式设备(如单片机、传感器等)进行通信的软件程序。 首先,我们需要创建一个新的MFC应用程序项目。在项目创建向导中,选择“对话框应用程序”作为项目类型,并选择适当的应用程序选项。 接下来,在对话框资源编辑器中,我们可以添加需要的控件,如按钮、文本框、列表框等。这些控件可以用来展示收到的串口数据、发送数据给设备、控制设备的开关等。 然后,我们需要添加串口通信的相关代码。首先,我们需要打开串口,并设置相关的串口参数,如波特率、数据位、校验位等。然后,我们可以使用串口的读取和写入函数,来实现与设备的数据交换。 在对话框类的成员函数中,我们可以编写相应的事件处理函数,比如当用户点击按钮时,发送指定的数据给设备。我们还可以编写串口数据接收的回调函数,用于处理从设备接收到的数据。 最后,我们可以在建立好的对话框界面中,测试编写的串口上位机程序。我们可以通过按钮来发送数据给设备,并通过文本框或列表框来显示从设备接收到的数据。 总结来说,用VS2017 MFC编写串口上位机可以通过创建应用程序项目、添加控件、编写串口通信代码和事件处理函数等步骤来实现。最终的目的是建立一个用户友好的界面,用于与嵌入式设备进行数据通信和控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

madao1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值