【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )

时间:2022-09-08 08:30:08


                向无数拼命工作的 程序猿 及 攻城狮 致敬!【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )

  1. 软硬件平台简介      

        CPUP4 2G及以上兼容于80x86架构的*处理器

        内存:1G及以上

        硬盘:80G及以上

        网卡:100M及以上

         操作系统:Windows XP及以上

        软件:VS2010/2012/2013  Visual C++ 6.0  Keil uVision3-4   STC_ISP_V488/友善串口助手

        硬件:众多、不胜数

2.总体设计思想

    串口通讯把数据的字节分解成单个的二进制比特流依次传输,其结构简单,连接线少,应用非常广泛。实现串口通信的方法很多。如:利用标准通信函数实现串口通信、利用API实现串口通信和利用ActiveX控件实现。

    本文主要采用ActiveX控件Microsoft Communications Control(MSComm)编程,Windows平台先进的ActiveX技术使得对串口编程不再需要处理烦琐的细节。利用已有的AxtiveX控件,只需要编写少量的代码,就可以轻松高效地完成任务。

    以下对ActiveX控件属性进行简单介绍,在ClassWizard中为新创建的通信控件定义成员对象(CMSComm m_comm),通过该对象便可以对串口属性进行设置,MSComm控件共有27个属性,这里只介绍其中几个常用属性:

CommPort:设置并回通讯端口号

  • Settings :以字符/其他的形式设置并返回波特率、奇偶校验、数据位、停止位。
  • PortOpen :设置并返回通讯端口的状态,也可以打开和关闭端口。
  • Input :   从接收缓冲区返回和删除字符。
  • Output :  向发送缓冲区写一个字符串。
  • InputLen :设置每次 Input 读入的字符个数,缺省值为 0 ,表明读取接收缓冲区中的全部内容。
  • InBufferCount :返回接收缓冲区中已接收到的字符数,将其置 0 可以清除接收缓冲区。
  • InputMode :定义 Input 属性获取数据的方式 ( 0 :文本方式;为 1 :二进制方式 )
  • RThreshold SThreshold :表示在 OnComm 事件发生之前,接收缓冲区或发送缓冲区中可以接收的字符数。

3.具体设计截面图

   

    1、建立应用工程

          》》》》(1)以VC++60为例:

                       创建一个基于对话框的MFC应用程序项目,选择Project菜单下Add to Project子菜单

                       中的Components and Controls选项,在弹出的对话框中双击Registered

                       ActiveX Controls项,则所有注册过的ActiveX控件出现在列表框中。选择Microsoft

                       Communications Controlversion 60,单击insert按钮即可将通信控件插入该工

                       程。添加该控件到对话框中,设置控件ID号为IDC _MSCOMM.

          》》》》(2)以VS2010为例,具体参考此链接:

    2、添加界面控件

           将对话框中的按钮“取消”删除,将“确定”按钮改为“退出”。在对话框中添加适当的界面控件。

           本实验中需添加的标注用的静态控件、用于选择串口和设置波特率的组合框分别设置控件ID号为

           IDC_COMBO_SELECT和IDC _COMBO_BTL SET、添加控制开始发送/接收按钮控件并设置控件ID号为

           IDC_BUTTON_START,添加用于输入发送数据和输出接收数据的编辑框并设置控件ID号为

           IDC_EDIT_SEND和IDC_EDIT_RECEVE,同时为其设置各种属性。


-----------------------------分割分割分割--------------------------------------------

      添加完后如下图

                                                                 【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 ) 

3、映射控件通用消息

   (1)打开MFC ClassWizard对话框,单击Member Valuable为相应控件添加变量。添加变量名和类型如下表:

控件ID号

变量名

变量类似

IDC_EDIT_RECEVE

CString

m_strReceive

IDC_EDIT_SEND

CString

m_strSend

IDC_MSCOMM

CMSComm

m_MScomm

IDC_PORT

int

m_nPort

如下图:

                                                             【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 ) 

4为对应控件添加代码

1为按钮IDC_BUTTON_OPEN添加单击响应函数void CMyDlg::OnButtonOpen();函数代码如下:

   

CMyDlg::OnButtonOpen();函数代码如下:
void CMyDlg::OnButtonOpen()
{
// TODO: Add your control notification handler code here
if(m_MSComm.GetPortOpen())
{
AfxMessageBox(_T("亲,请先关闭串口!"));
return;
}
UpdateData(TRUE);
if(m_nPort==-1)
{
AfxMessageBox(_T("亲,请选择串口!"));
return;
}
m_MSComm.SetCommPort(m_nPort);//选择com
m_MSComm.SetInBufferSize(1024);//设置输入缓冲区的大小
m_MSComm.SetOutBufferSize(1024);//设置输出缓冲区的大小
m_MSComm.SetInputLen(0);//设置当前接收区数据长度为0
m_MSComm.SetInputMode(1);//1:表示以二进制方式检取数据
m_MSComm.SetRThreshold(1);
/* 接收缓冲区有1个及1个以上字符时,将引发接收数据的Oncomm事件*/
m_MSComm.SetPortOpen(TRUE);//打开串口
if(m_MSComm.GetPortOpen())
{
GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(TRUE);
}
else
{
m_MSComm.SetOutBufferCount(0);
CString strInfo=_T("");
strInfo.Format(_T("啊哦!打开串口COM%d失败!"),m_nPort);
AfxMessageBox(strInfo);
GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE);
}
}

2)为按钮IDC_BUTTON_SEND添加单击响应函数void CMyDlg::OnButtonSend();函数代码如下:

   

  void CMyDlg::OnButtonSend() 
{
// TODO: Add your control notification handler code here
if(!m_MSComm.GetPortOpen())
{
AfxMessageBox(_T("亲,请先打开串口!"));
return;
}
UpdateData(TRUE); //读取编辑框内容
int nSendLength=m_strSend.GetLength();//要发送的字符串送字符数组
CByteArray ByteArray;
ByteArray.RemoveAll();
ByteArray.SetSize(nSendLength);
for(int i=0;i<nSendLength;i++)
ByteArray.SetAt(i,m_strSend[i]);//将字符数组型
m_MSComm.SetOutput(COleVariant(ByteArray));//发送数据
}

3)为按钮IDC_BUTTON_CLOSE添加单击响应函void CMyDlg::OnButtonClose();函数代码如下:

   

void CMyDlg::OnButtonClose() 
{
// TODO: Add your control notification handler code here
if(!m_MSComm.GetPortOpen())
{
AfxMessageBox(_T("亲,请先打开串口!"));
return;
}
m_MSComm.SetPortOpen(FALSE);
GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE);
}

(4)为组合框添加初始化函数void CMyDlg::OnSelchangeBps();编辑加入代码如下

void CMyDlg::OnSelchangeBps() 
{
// TODO: Add your control notification handler code here
UpdateData(true);
int nlndex=m_bps.GetCurSel();a=nlndex;
switch(nlndex)
{
case 0: m_MSComm.SetSettings("19200,n,8,1"); break;
case 1: m_MSComm.SetSettings("14400,n,8,1"); break;
case 2: m_MSComm.SetSettings("9600,n,8,1"); break;
case 3: m_MSComm.SetSettings("4800,n,8,1"); break;
default: break;
} /*参数1表示每当串口接收缓冲区中有多于或等于
1个字符时将引发一个接收数据的OnComm事件*/
UpdateData(false);
}

  (5IDC _MSCOMM添加消息映射函数void CMyDlg::OnOnCommMscomm()以便当接收缓冲区有数据时做相应处理。添加代码如下:

void CMyDlg::OnOnCommMscomm() 
{
// TODO: Add your control notification handler code here
VARIANT varinant_Input;
COleSafeArray safearray_Input;
BYTE RcvData[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strTmp=_T("");

if(m_MSComm.GetCommEvent()==2)//事件值为2表示接收缓冲区内有字符
{
varinant_Input=m_MSComm.GetInput(); //读缓冲区
safearray_Input=varinant_Input;
/*--VARIANT型变量转换为ColeSafeArray型变量--*/
int Length=safearray_Input.GetOneDimSize();//得到有效数据长度
for(long i=0;i<Length;i++)
{
safearray_Input.GetElement(&i,RcvData+i);//转换为BYTE型数组
BYTE bt=*(char*)(RcvData+i);//字符型
if(b==1)strTmp.Format("%c",bt);//将字符送入临时变量strtemp存放
else strTmp.Format("%d",bt);
m_strReceive+=strTmp;//加入接收编辑框对应字符串
}
UpdateData(FALSE);//更新编辑框内容,显示接收到的数据
}
}

   

  (6)数据

void CMyDlg::OnRadio1() 
{
// TODO: Add your control notification handler code here
b=true;
}
void CMyDlg::OnRadio2()
{
// TODO: Add your control notification handler code here
b=false;
}

接收形式 添加函数void CMyDlg::On Radio 添加代码如下:


  5.生成可执行的EXE文件

编译、链接、运行会相应工程目录下的debug目录下生成可执行的EXE文件。连接好串口线后运行该文件可进行串口通信。运行如下

                            【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 ) 

五、软件流程图

符号设定

        流程开始符号:      【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )

          流程结束符号:       【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )

         判定符号:           【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )

        路由符号:          【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )

        文档输出:  【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )

 

在概念设计中,我采用单向策略.用自顶向下设计一个全局概念结构的框架,以它为骨架集成由自底向上策略中设计的各局部概念结构.

、测试结果截图

笔记本电脑运行如下:(分整数和字符两种显示格式)

A.整数显示

                                                                         【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 ) 

B.字符显示

                                                                        【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 ) 

C.外设测试运行如下:

                             【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 ) 

【C++】串口通信IN C++(适用于Microsoft Visual Studio 2010/2012/2013 ,VC++6.0 )转载请注明来源,么么哒!原创声明:本文为-Sure-原创作品,转载时请注明“转自-Sure-”及原文链接。