VC2019 CMSComm 控件串口通信编程教程Step by Step

18 篇文章 5 订阅

1.打开VS2019,点击“创建新项目”

2.在模版搜索栏中输入MFC,如果你的VS2019装有C++ MFC组件,会显示下图界面,点击MFC应用,再点击下一步。

3.输入项目名称及存储路径,点击创建

4.在应用程序类型中选择基于对话框,点击完成

初始界面如下:

5.点击“工具”菜单,再点击“选择工具箱项”

6.在弹出对话框中,点击“com组件”,然后在下面列表中选择“Microsoft Communications Control…”,然后点击“确定”

 

7.将工具箱里的“Microsoft Communications Control…”拖到设计的对话框里,如下:

c:\\Windows\\SysWOW64\\comctl32.ocx 再点确定,注册。注意我的系统是Win7 64位。

10.在弹出对话框中,点击MFC,选中右边列表框中的ActiveX控件中的MFC类,点击添加

11.在弹出对话框中,可用类型库栏,选中Microsoft Comm Control 6.0….选中右下列表框中的IMSComm,在点击》,点击确定。

12.打开项目资源管理器,可看到,已添加了与串口通信有关的文件。

13.按Ctrl+F5试运行一下,看是否存在错误,结果如下,没有错误。

14.对话框界面设计,由于是演示程序,界面设计得比较简单。

15.位串口设置中的五个CComboBox及发送接收区的编辑框添加关联变量,编辑框还额外关联CString变量分别为:strEditRevc,strEditInput。

16.在DemoCSCommDlg的头文件中包含CMSComm.h并在头文件中定义CMSComm变量

mctr_SComm

17. 将mctr_SComm关联到对话框中的Microsoft Communications Control控件

18.串口设置中的CComboBox控件初始化,为实现CComboBox的初始化数据按输入顺序排列,需将CComboBox控件属性表中的排序设为False,为便于查看初始化数据加入,在CDemoCSCommDlg::OnInitDialog()中进行。

//初始化端口CComboBox控件

    mctr_Combobox_Port.AddString(_T("COM1"));

    mctr_Combobox_Port.AddString(_T("COM2"));

    mctr_Combobox_Port.AddString(_T("COM3"));

    mctr_Combobox_Port.AddString(_T("COM4"));

    mctr_Combobox_Port.AddString(_T("COM5"));

    mctr_Combobox_Port.AddString(_T("COM6"));

    mctr_Combobox_Port.AddString(_T("COM7"));

    mctr_Combobox_Port.AddString(_T("COM8"));

    mctr_Combobox_Port.AddString(_T("COM9"));

    mctr_Combobox_Port.AddString(_T("COM10"));

    mctr_Combobox_Port.SetCurSel(0);

    //初始化波特率CComboBox控件

    mctr_Combobox_Baudrate.AddString(_T("1200"));

    mctr_Combobox_Baudrate.AddString(_T("2400"));

    mctr_Combobox_Baudrate.AddString(_T("4800"));

    mctr_Combobox_Baudrate.AddString(_T("9600"));

    mctr_Combobox_Baudrate.AddString(_T("12800"));

    mctr_Combobox_Baudrate.AddString(_T("14400"));

    mctr_Combobox_Baudrate.AddString(_T("19200"));

    mctr_Combobox_Baudrate.AddString(_T("25600"));

    mctr_Combobox_Baudrate.AddString(_T("28800"));

    mctr_Combobox_Baudrate.AddString(_T("38400"));

    mctr_Combobox_Baudrate.AddString(_T("56000"));

    mctr_Combobox_Baudrate.SetCurSel(3);

    //初始化校验位CComboBox控件

    mctr_Combobox_Parity.AddString(_T("E"));

mctr_Combobox_Parity.AddString(_T("M"));

    mctr_Combobox_Parity.AddString(_T("N"));

    mctr_Combobox_Parity.AddString(_T("O"));

    mctr_Combobox_Parity.AddString(_T("S"));

    mctr_Combobox_Parity.SetCurSel(2);

    //初始化数据位CComboBox控件

    mctr_Combobox_Data.AddString(_T("4"));

    mctr_Combobox_Data.AddString(_T("5"));

    mctr_Combobox_Data.AddString(_T("6"));

    mctr_Combobox_Data.AddString(_T("7"));

    mctr_Combobox_Data.AddString(_T("8"));

    mctr_Combobox_Data.SetCurSel(4);

    //初始化停止位CComboBox控件

    mctr_Combobox_StopBit.AddString(_T("1"));

    mctr_Combobox_StopBit.AddString(_T("1.5"));

    mctr_Combobox_StopBit.AddString(_T("2"));

    mctr_Combobox_StopBit.SetCurSel(0);

20.在串口未打开时,关闭串口按钮应该是不可操作,因此也需要,在初始化中设置。

//初始化关闭串口按钮

    CButton* pButton;

    pButton = (CButton*)GetDlgItem(IDC_BUTTON_CLOSE_COMM);

    pButton->EnableWindow(0);

21."DemoCSCommDlg.h"中定义两个BOOL变量bOpen,bRecv用以标记串口打开状态及是否接收数据。并在构造函数中初始化这两个变量,在 CDemoCSCommDlg::OnPaint()中添加码

// CSComm open/close flag

    bool bOpen;

    // SComm receive data enable/disable flag

    bool bRecv;

//变量初始化:

CDemoCSCommDlg::CDemoCSCommDlg(CWnd* pParent /*=nullptr*/)

    : CDialogEx(IDD_DEMOCSCOMM_DIALOG, pParent)

{

    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    bOpen = 0;

    bRecv = 1;

}

//CDemoCSCommDlg::OnPaint()中添加以下代码:

{

CButton* pButton;

    if (bOpen)

    {

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_OPEN_COMM);

pButton->EnableWindow(0);

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_CLOSE_COMM);

        pButton->EnableWindow(1);

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_OPEN_SEND);

        pButton->EnableWindow(1);

    }

    else

    {

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_OPEN_COMM);

        pButton->EnableWindow(1);

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_CLOSE_COMM);

        pButton->EnableWindow(0);

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_OPEN_SEND);

        pButton->EnableWindow(0);

    }

    if (bRecv)

    {

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_STOP_RECV);

        pButton->SetWindowTextW(_T("停止接收"));

    }

    else

    {

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_STOP_RECV);

        pButton->SetWindowTextW(_T("接收数据"));

    }

22."DemoCSCommDlg.h"中定义串口初始化函数

23. 在“DemoCSCommDlg.cpp”中实现,源码如下:

void CDemoCSCommDlg::InitScomm(short mscommPort, CString mSetsettings)

{

    // TODO: 在此处添加实现代码.

    mctr_SComm.put_CommPort(mscommPort);//选择nCom口

   

    mctr_SComm.put_InputMode(1);//以文本方式获取输入数据

    mctr_SComm.put_InBufferSize(1024);//输入缓冲区大小为1024byte

    mctr_SComm.put_OutBufferSize(1024);//输出缓冲区大小为1024byte

    mctr_SComm.put_Settings(mSetsettings);//设置串口参数

}

24.鼠标移动到CSComm控件上按右键,为其添加事件处理程序

在此函数中添加如下代码,实现数据接收。

void CDemoCSCommDlg::OnCommMscomm1()

{

   

    VARIANT variant_inp;

    COleSafeArray safearray_inp;

    CString strtemp;

    CByteArray byteArr;

    short nEvent = mctr_SComm.get_CommEvent();

    if (nEvent == 2 && bRecv == TRUE)

    {

        variant_inp = mctr_SComm.get_Input();//读缓input冲区

        safearray_inp = variant_inp;//variant数据转换成colesafearray型变量

        safearray_inp.GetByteArray(byteArr);

        byteArr.FreeExtra();

int len = byteArr.GetSize();

        for (int i = 0; i < len; i++)

        {

            BYTE bt = byteArr[i];

            strtemp.Format(L"%c", bt);

            strEditRevc += strtemp;

        }

        mctr_Edit_Revc.SetWindowTextW(strEditRevc);

    }

}

25. 对话框上的所有按钮添加事件处理程序及实现代码:

afx_msg void OnBnClickedButtonOpenComm();

afx_msg void OnBnClickedButtonSend();

afx_msg void OnBnClickedButtonCloseComm();

afx_msg void OnBnClickedButtonClear();

afx_msg void OnBnClickedButtonStopRecv();

//打开串口

void CDemoCSCommDlg::OnBnClickedButtonOpenComm()

{

    // TODO: 在此添加控件通知处理程序代码

    short sPort = mctr_Combobox_Port.GetCurSel() + 1;

    CString str, str1;

    str.Empty();

    mctr_Combobox_Baudrate.GetLBText(mctr_Combobox_Baudrate.GetCurSel(), str1);

    str += str1;

    mctr_Combobox_Parity.GetLBText(mctr_Combobox_Parity.GetCurSel(), str1);

    str += str1;

    mctr_Combobox_Data.GetLBText(mctr_Combobox_Data.GetCurSel(), str1);

    str += str1;

    mctr_Combobox_StopBit.GetLBText(mctr_Combobox_StopBit.GetCurSel(), str1);

    str += str1;

    str = "9600,n,8,1";

    InitScomm(sPort, str);

   

    if (!mctr_SComm.get_PortOpen())

        try

        {

            mctr_SComm.put_PortOpen(1);//打开串口

        }

        catch (CException* e)

        {

            MessageBox(_T("打开串口失败"));

            e->ReportError();

        e->Delete();

        }

    if (mctr_SComm.get_PortOpen())

    {

        MessageBox(L"打开串口成功");

        mctr_SComm.put_RThreshold(1);//每当串口接收缓冲区有多余或等于1个字符时将引发一个接收数据的oncomm事件

        mctr_SComm.put_InputLen(0);//设置当前接收区数据长度为0,即一次读取全部数据

        mctr_SComm.get_Input();//预读缓冲区以清空残留数据

        //读写超时设置

        volatile HANDLE m_hCom;

        COMMTIMEOUTS m_TimeOuts;

        m_hCom = (HANDLE)mctr_SComm.get_CommPort();

        m_TimeOuts.ReadIntervalTimeout = MAXDWORD;

        m_TimeOuts.ReadTotalTimeoutMultiplier = 0;

        m_TimeOuts.ReadTotalTimeoutConstant = 0;

        m_TimeOuts.WriteTotalTimeoutMultiplier = 50;

        m_TimeOuts.WriteTotalTimeoutConstant = 2000;

        SetCommTimeouts(m_hCom, &m_TimeOuts);

        //对话框界面更新

        bOpen = 1;

        CButton* pButton;

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_OPEN_COMM);

        pButton->EnableWindow(0);

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_SEND);

        pButton->EnableWindow(1);

        pButton = (CButton*)GetDlgItem(IDC_BUTTON_CLOSE_COMM);

        pButton->EnableWindow(1);

    }

    else

    {

        MessageBox(L"打开串口失败");

    }

}

//发送数据

void CDemoCSCommDlg::OnBnClickedButtonSend()

{

    // TODO: 在此添加控件通知处理程序代码

    CString strSendData;

    COleVariant coleData;

    UpdateData();

    mctr_Edit_Input.GetWindowText(strSendData);

    coleData = (COleVariant)strSendData;

    mctr_SComm.put_Output((VARIANT)coleData);

}

//关闭串口

void CDemoCSCommDlg::OnBnClickedButtonCloseComm()

{

    mctr_SComm.put_PortOpen(0);

    bOpen = 0;

    CButton* pButton;

    pButton = (CButton*)GetDlgItem(IDC_BUTTON_OPEN_COMM);

    pButton->EnableWindow(1);

    pButton = (CButton*)GetDlgItem(IDC_BUTTON_SEND);

    pButton->EnableWindow(0);

    pButton = (CButton*)GetDlgItem(IDC_BUTTON_CLOSE_COMM);

    pButton->EnableWindow(0);

}

//清空接收区

void CDemoCSCommDlg::OnBnClickedButtonClear()

{

    strEditRevc.Empty();

    mctr_Edit_Revc.SetWindowTextW(strEditRevc);

   

}

//接收数据/停止接收

void CDemoCSCommDlg::OnBnClickedButtonStopRecv()

{

    CButton* pButton;

    pButton = (CButton*)GetDlgItem(IDC_BUTTON_STOP_RECV);

    if (bRecv)

    {

        bRecv = FALSE;

        pButton->SetWindowTextW(L"接收数据");

    }

    else

    {

        bRecv =TRUE;

        pButton->SetWindowTextW(L"停止接收");

    }

}

25.实测,由于电脑没有9Pin串口,先用CH340(USB转串口)模块,将TxD与RxD用跳帽短接,进行发送与接收测试。

  • 8
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bill66

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

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

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

打赏作者

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

抵扣说明:

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

余额充值