基于API的MFC串口通信程序编写

来源:互联网 发布:matlab从excel导入数据 编辑:程序博客网 时间:2024/05/16 07:45

问题描述:很多同学接触的MFC的第一个较为完整和有用的程序就是串口通信程序。由于MFC是基于控件和对话框的,因此对于从纯文本程序到MFC会有一个较为痛苦的转变过程(比如本人)。当然基于文本或者MFC的编程思想其基础是一致的,需要熟悉的只是如何将需要操作的程序添加进MFC中通过点击按钮触发的事件函数中去。只要将适当的处理程序添加进合适的位置,就很容易编写出简单易懂的小软件。

程序效果图:



下面大家可以跟着我一步一步操作,最后得到如图所示的结果。

步骤(串口调试助手和虚拟串口连接自己提前搞好):

一,建立MFC工程——>命名为”串口通信“——>选择MFC应用程序——>选择基于对话框——>点完成



二,在工具箱里选择Edit Control,Button,Combox和Static Text,分别在其属性的caption中更改其显示名称,如图所示:



三,添加变量

右键点击选择串口号下面的下拉框,选择添加变量,结果如图所示:



同理,在选择波特率下面的下拉框,选择添加变量如图所示:


 

在发送输入框下面的编辑框,添加变量:


 

在接收输出框下面的编辑框,添加变量:


 

为串口通信对话框添加两个变量为全局变量:


 

 

四,添加代码

BOOL C串口通信Dlg::OnInitDialog()函数的// TODO:  在此添加额外的初始化代码下面添加代码为:

CString str;

int i;

for (i = 0; i<15; i++)

{

str.Format(_T("com %d"), i + 1);

m_comb1.InsertString(i, str);

}

m_comb1.SetCurSel(0);//预置COM口

 

//波特率选择组合框

CString str1[12] = { _T("300"), _T("600"), _T("1200"), _T("2400"), _T("4800"), _T("9600"), _T("19200"), _T("38400"), _T("43000"), _T("56000"), _T("57600"), _T("115200") };

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

{

int judge_tf = m_comb2.InsertString(i, str1[i]);//m_comb2.AddString(str1[i]);

if ((judge_tf == CB_ERR) || (judge_tf == CB_ERRSPACE))

MessageBox(_T("build baud error!"));

}

m_comb2.SetCurSel(5);//预置波特率为"9600"

 

双击打开串口按钮,为该按钮添加事件函数void C串口通信Dlg::OnBnClickedOk()(该函数名之所以为这个是因为最开始我把确定按钮直接改成了打开串口按钮)在该函数中添加:

 

CString PortName,str;

 

PortName.Format(_T("com%d"),m_comb1.GetCurSel()+1);//选择串口m_ctrlComm.put_CommPort(m_comb1.GetCurSel()+1);//选择串口

hComm=CreateFile(PortName,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);//以可读写,独占方式,无安全属性,已存在通讯设备,异步IO(FILE_FLAG_OVERLAPPED),通讯设备不能以模板打开方式打开

 

if(hComm==INVALID_HANDLE_VALUE)

{

m_strTXData="Open Comm Failed";

UpdateData(FALSE);

}

else

{

m_strTXData="Open Comm Success, the handle is:";

str.Format(_T("%d"),hComm);

m_strTXData+=str;

UpdateData(FALSE);}

//设置串口参数

DCB dcb;

int rate;

 

switch(m_comb2.GetCurSel()+1)

{

case 1:rate=300;break;

case 2:rate=600;break;

case 3:rate=1200;break;

case 4:rate=2400;break;

case 5:rate=4800;break;

case 6:rate=9600;break;

case 7:rate=19200;break;

case 8:rate=38400;break;

case 9:rate=43000;break;

case 10:rate=56000;break;

case 11:rate=57600;break;

case 12:rate=115200;break;

default:rate=9600;

}

 

//memset(&dcb,0,sizeof(dcb));

GetCommState(hComm,&dcb);

dcb.DCBlength=sizeof(dcb);

dcb.BaudRate=rate;

    dcb.Parity=NOPARITY;

    dcb.fParity=0;

    dcb.StopBits=ONESTOPBIT;

    dcb.ByteSize=8;

 

SetCommState(hComm,&dcb);

 

PurgeComm(hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);

SetTimer(1,10,NULL);

    //CDialogEx::OnOK();

并且注释掉CDialogEx::OnOK();否则运行程序时点击该按钮会导致对话框退出(不信可以试试)。

 

    同理,为关闭串口按钮添加函数void C串口通信Dlg::OnBnClickedCancel()(该函数名之所以为这个是因为最开始我把取消按钮直接改成了关闭串口按钮),且在函数中添加代码:

KillTimer(1);

CloseHandle(hComm);

同理为发送按钮添加代码:

UpdateData(TRUE);//读取编辑框内容

char strTX[1024] = { 0 };

BOOL bWrite = TRUE;

BOOL bResult = TRUE;

DWORD BytesSent = 0;

CString str;

//HANDLE m_hWriteEvent;

int i = 0;

for (i = 0; i<m_strTXData.GetLength(); i++)

strTX[i] = (char)m_strTXData.GetAt(i);

bResult = WriteFile(hComm, strTX, m_strTXData.GetLength(), &BytesSent, NULL);

 

为清空按钮添加代码:

m_strRXData="";

UpdateData(FALSE);

 

点击C串口通信Dlg,在其属性中点击闪电符号右边的消息符号,选择WM_TIMER并添加事件处理函数void C串口通信Dlg::OnTimer(UINT_PTR nIDEvent),并添加代码:

 

BOOL bResult = TRUE;

DWORD dwError = 0;

DWORD BytesRead = 0;

char strRX[1024] = { 0 };

 

ClearCommError(hComm, &dwError, &ComStat);

if (ComStat.cbInQue>0)

{

bResult = ReadFile(hComm, strRX, ComStat.cbInQue, &BytesRead, NULL);

if (bResult)

{

m_strRXData += strRX;

UpdateData(FALSE);

}

}

五,编译代码,调试结果如图所示:

 

 

六,总结

本文根据网上的参考文献编写了一个基于APIMFC串口通信程序,网上现有的基于API的通信程序大多不是MFC窗口,而使用MFC的大多采用mscomm控件。因此如何在MFC下编写基于API串口通信程序成为了本文的亮点。

本文编写的串口通信程序是同步I/O以及定时查询工作方式,异步I/O和事件驱动方式正在学习,以后找时间会上传,希望大家都能学到东西。

注:本文代码中一些变量并未使用,可以删去。

本文重在操作,而原理部分有很多参考,如下链接所示均为很好的参考文献:

http://blog.csdn.net/jax_lee/article/details/6764394

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29261327&id=4299375

 

1 0
原创粉丝点击