首页 VC6.0MFC串口通信编写全过程

VC6.0MFC串口通信编写全过程

举报
开通vip

VC6.0MFC串口通信编写全过程其于MFC的串口调试助手编辑过程新建打开VC6.0文件新建工程MFCAppWiard(exe)位置(选择保存工程位置)工程名称(输入工程名XXXX)确定选择基本对话框下一步下一步下一步选择(CXXXXDlg)完成确定在生成的基本对话框内将不需要按钮及提示框(自动生成的“确定”“取消”及提示框)删除或修改使用,至此基本框架完成如下图:此控件(标志)是下面步骤添加进来的串口控件往生成的基本框架中添加控件1、因为控件列表框内没有串口通信用到的通信控件,所以要先添加到控件列表框内再将控件添加到基本框内使用,步骤如下:菜单栏...

VC6.0MFC串口通信编写全过程
其于MFC的串口调试助手编辑过程新建打开VC6.0文件新建工程MFCAppWiard(exe)位置(选择保存工程位置)工程名称(输入工程名XXXX)确定选择基本对话框下一步下一步下一步选择(CXXXXDlg)完成确定在生成的基本对话框内将不需要按钮及提示框(自动生成的“确定”“取消”及提示框)删除或修改使用,至此基本框架完成如下图:此控件(标志)是下面步骤添加进来的串口控件往生成的基本框架中添加控件1、因为控件列表框内没有串口通信用到的通信控件,所以要先添加到控件列表框内再将控件添加到基本框内使用,步骤如下:菜单栏工程添加到工程Componentsandcontrols…RegisteredActiveXControls选择“MicrosoftCommunicationsControl,version6.0”Insert确定OK关闭此子窗口完成添加操作标志如上图所示。基本框架2、将刚才添加添加到控件列表框内的串口控件添加到基本框架内点击控件列表框内的串口控件,此时光标变为“十”形,在基本框架内随意划取一矩形区域,即可以添加串口控件,不需要修改此控件的大小及位置,因为程编译运行后此控件是看不到的,步骤结果如下图:3、继续往基本框架内添加用于编辑发送数据的输入编辑框及输出编辑框,同理选择控件列表框内的“编辑框控件”,以相同的操作即可添加两个编辑窗口及一个按纽控件如下图所示:选择其中任意一个作为输入编辑框及输出编辑框这两个窗口需要修改大小及位置,因为程序运行后将会显示而串口通信控件则不显示,上图是运行后的效果。4、对以上四个控件编程步骤如下:a、右击串口通信控件建立类向导MembervariablesControlIDS中选择IDC_MSCOMM1addvariable…Membervariablename中输入控件变量名m_ctrlComm(变量名可以随意选取,但程序中应与所取变量名一致)OK确定b、右击编辑框、属性、常规、ID:中输入ID号,此编辑框用于接收显示数据的其ID号为IDC_EDIT_RXDATA(可以随意选取,但程序中应与所取ID号一致),再在此窗口的样式中勾选”多行”,同时将“自动水平滚动(T)”勾选去掉,再勾选“垂直滚动(V)”,此勾选操作是用于垂直多行显示的,按回车后即可输入;同理右击另一编辑框输入ID号为IDC_EDIT_TXDATA此编辑框用于编辑发送数据的,同样也选上用于垂直多行显示,发送框可以不用垂直多行显示;再为按钮控件添加ID号,为IDC_BUTTON_MANUALSEND,并将标题中的“Button1”改为“发送”,功能是按一次就把发送编辑框中的内容发送一次。C、为以上两个编辑框添加变量,与串口通信控件一样添加,为IDC_EDIT_RXDATA添加CString型变量m_strRXData;为IDC_EDIT_TXDATA添加CString型变量m_strTXData。说明:m_strRXData和m_strTXData分别用来放入接收和发送的字符数据。D、添加串口事件消息处理函数OnComm()打开ClassWizard->MessageMaps,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm,(好记而已)OK。这个函数是用来处理串口消息事件的,如每当串口接收到数据,就会产生一个串口接收数据缓冲区中有字符的消息事件,我们刚才添加的函数就会执行,我们在OnComm()函数加入相应的处理代码就能实现自已想要的功能了。在函数中加入如下代码:提示1:此句以下才是我们要添加的语句代码段1:voidCScommTestDlg::OnComm(){//TODO:AddyourcontrolnotificationhandlercodehereVARIANTvariant_inp;//定义一个VARIANT类对象COleSafeArraysafearray_inp;//定义一个COleSafeArray对象LONGlen,k;BYTErxdata[2048];//设置BYTE数组AN8—intterthatisnotsigned.CStringstrtemp;if(m_ctrlComm.GetCommEvent()==2)//事件值为2表示接收缓冲区内有数据{////以下你可以根据自己的通信 协议 离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载 加入处理代码variant_inp=m_ctrlComm.GetInput();//读缓冲区safearray_inp=variant_inp;//VARIANT型变量转换为ColeSafeArray型变量len=safearray_inp.GetOneDimSize();for(k=0;kAppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);}}提示3:此句以下才是我们要添加的语句//Settheiconforthisdialog.Theframeworkdoesthisautomatically//whentheapplication'smainwindowisnotadialog提示4:此5句是我们下面要用到的暂时可以不用理会SetIcon(m_hIcon,TRUE);//SetbigiconSetIcon(m_hIcon,FALSE);//Setsmallicon//TODO:Addextrainitializationhere//m_ComboBox.SetCurSel(0);//打开软件时串口选择框默认显示COM1//m_BaudRate_M.SetCurSel(0);//打开软件时波特率选择框默认显示9600//m_Date_Select_M.SetCurSel(0);//打开软件时数据位选择框默认显示8//m_StopBit_M.SetCurSel(0);//打开软件时停止位选择框默认显示1//m_ParityCheck_M.SetCurSel(0);//打开软件时奇偶校验选择框默认显示无校验N//下面if语句用于打开默认串口/************************************************************/if(m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(FALSE);//关闭串口}m_ctrlComm.SetCommPort(1);//打开软件时默认使用COM1串口if(!m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(TRUE);//打开串口}else{AfxMessageBox("cannotopenserialport");}/*************************************************************/m_ctrlComm.SetSettings("9600,n,8,1");//打开软件时端口设置默认为波特率9600,无校验位,8位数据,1位停止位m_ctrlComm.SetInputMode(1);//1:表示以二进制方式检取数据m_ctrlComm.SetRThreshold(1);//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件m_ctrlComm.SetInputLen(0);//设置当前接收区数据长度为0m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据returnTRUE;//returnTRUEunlessyousetthefocustoacontrol}F、发送数据,先为发送按钮添加一个单击消息即BN_CLICKED处理函数,打开ClassWizard->MessageMaps,选择IDC_BUTTON_MANUALSEND,双击BN_CLICKED添加OnButtonManualsend()函数,并在函数中添加如下代码:代码段3:voidCSCommTestDlg::OnButtonManualsend(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(TRUE);//读取编辑框内容m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数据}此时运行程序,在发送编辑框中随意输入数,单击发送按钮,若出错则修改后再测试,直到成功再进行以下操作。5、添加两个“组框”或“静态文本”控件,调整位置及大小,在标师处输入提示文字,这两个控件不用编程,效果如下图:6、添加5个“静态文本”控件并由属性修改其标题,均不用编程,效果如下图:7、添加5个“组框”控件,效果如下图:逐一对各个组框属性编辑如下:串口号:常规ID:IDC_COMBO_CommSelect数据输入列表框项目(N):COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9(注意每输入一个数据选项以Ctrl+Enter回车后再输入下一个数据选项)样式将“分类勾选去掉”进入类向导添加变量,为IDC_COMBO_CommSelect添加一个value类int型变量m_Index,点击OK后,再添加一个Control类CComboBox型变量m_ComboBox点击OK最后“确定”波特率:常规ID:IDC_COMBO_BaudRate_Select数据输入列表框项目(N):9600、14400、19200、38400、56000、57600、115200、128000、256000样式将“分类勾选去掉”进入类向导添加变量,为IDC_COMBO_BaudRate_Select添加一个value类int型变量m_BaudRate点击OK后,再添加一个Control类CComboBox型变量m_BaudRate_M点击OK最后“确定”数据位:常规ID:IDC_COMBO_Date_Select数据输入列表框项目(N):8、7、6、5、4样式将“分类勾选去掉”进入类向导添加变量,为IDC_COMBO_Date_Select添加一个value类int型变量m_Date_Select点击OK后,再添加一个Control类CComboBox型变量m_Date_Select_M点击OK最后“确定”停止位:常规ID:IDC_COMBO_StopBit数据输入列表框项目(N):1、2样式将“分类勾选去掉”进入类向导添加变量,为IDC_COMBO_StopBit添加一个value类int型变量m_StopBit点击OK后,再添加一个Control类CComboBox型变量m_StopBit_M点击OK最后“确定”奇偶校验位:常规ID:IDC_COMBO_ParityCheck数据输入列表框项目(N):N、O、E、样式将“分类勾选去掉”进入类向导添加变量,为IDC_COMBO_ParityCheck添加一个value类int型变量m_ParityCheck点击OK后,再添加一个Control类CComboBox型变量m_ParityCheck_M点击OK最后“确定”说明:以上数据配置添加的Control类CComboBox型变量可能用不到,但value类必须为int型8、为各个列表框添加处理函数:A、在建立类向导中MessageMaps,objectIDs中选中IDC_COMBO_CommSelect再在Messages中选中CBN_SELCHANG双击后单击OK,再在Memberfuntions中双击刚才生成的函数进入程序编辑页面,添加程序代码如下:代码段4:voidCSCommTestDlg::OnSelchangeCOMBOCommSelect(){//TODO:Addyourcontrolnotificationhandlercodeherem_Index=((CComboBox*)GetDlgItem(IDC_COMBO_CommSelect))->GetCurSel();//当前选中的行((CComboBox*)GetDlgItem(IDC_COMBO_CommSelect))->SetCurSel(m_Index);//设置当前选中的行的内容为显示的内容if(m_ctrlComm.GetPortOpen())//当要改变时则要先关闭串口才可以用按键进行打开,所以先判断当前串口是否打开提示5:下面添加串口打开或关闭按钮后将用到此将用到此判断及以下语句{//如果是打开的则先关闭m_ctrlComm.SetPortOpen(FALSE);//关闭串口}SetDlgItemText(IDC_BUTTON1,"打开串口");//将打开或关才按钮改为"打开串口"显示状态}B、同理为IDC_COMBO_BaudRate_Select添加处理函数程序代码如下:代码段5:voidCSCommTestDlg::OnSelchangeCOMBOBaudRateSelect(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);m_BaudRate=((CComboBox*)GetDlgItem(IDC_COMBO_BaudRate_Select))->GetCurSel();//当前选中的行////***********************************************************////根据当前选中的值进行波特率设置///************************************************************/switch(m_BaudRate){case1:m_ctrlComm.SetSettings("14400,,,");break;case2:m_ctrlComm.SetSettings("19200,,,");break;case3:m_ctrlComm.SetSettings("38400,,,");break;case4:m_ctrlComm.SetSettings("56000,,,");break;case5:m_ctrlComm.SetSettings("57600,,,");break;case6:m_ctrlComm.SetSettings("115200,,,");break;case7:m_ctrlComm.SetSettings("128000,,,");break;case8:m_ctrlComm.SetSettings("256000,,,");break;default:m_ctrlComm.SetSettings("9600,,,");break;}//*************************************************////UpdateData(false);}C、同理为IDC_COMBO_Date_Select添加处理函数程序代码如下:代码段6:voidCSCommTestDlg::OnSelchangeCOMBODateSelect(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);m_Date_Select=((CComboBox*)GetDlgItem(IDC_COMBO_Date_Select))->GetCurSel();//当前选中的行///*******************************************************************************////********************************************************************************/switch(m_Date_Select){case1:m_ctrlComm.SetSettings(",,7,");break;case2:m_ctrlComm.SetSettings(",,6,");break;case3:m_ctrlComm.SetSettings(",,5,");break;case4:m_ctrlComm.SetSettings(",,4,");break;default:m_ctrlComm.SetSettings(",,8,");break;}//*********************************************************************************//UpdateData(false);}D、同理为IDC_COMBO_StopBit添加处理函数程序代码如下:代码段6:voidCSCommTestDlg::OnSelchangeCOMBOStopBit(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);m_StopBit=((CComboBox*)GetDlgItem(IDC_COMBO_StopBit))->GetCurSel();//当前选中的行///*******************************************************************************////********************************************************************************/switch(m_StopBit){case1:m_ctrlComm.SetSettings(",,,2");break;default:m_ctrlComm.SetSettings(",,,1");break;}//*********************************************************************************//UpdateData(false);}E、同理为IDC_COMBO_ParityCheck添加处理函数程序代码如下:代码段7:voidCSCommTestDlg::OnSelchangeCOMBOParityCheck(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData(true);m_ParityCheck=((CComboBox*)GetDlgItem(IDC_COMBO_ParityCheck))->GetCurSel();//当前选中的行///*******************************************************************************////********************************************************************************/switch(m_ParityCheck){case1:m_ctrlComm.SetSettings(",O,,");break;case2:m_ctrlComm.SetSettings(",O,,");break;default:m_ctrlComm.SetSettings(",N,,");break;}//*********************************************************************************//UpdateData(false);}此时应将代码段2:提示4中所指的那5个语句前的“//”删除9、串口添加打开或关闭按钮以同样的方式添加按钮,并将标题修改为“关闭串口”字样,为此按钮添加处理函数程序代码如下:代码段8:voidCSCommTestDlg::OnButton1Start(){//检查是否改变默认的串口值,没有改变m_Index的值是0的,否则则不为0if(m_Index<0)//串口的默认值没有改变{switch(m_ctrlComm.GetPortOpen())//点击打开或关闭串口按键时,根据当前串口是否打开进行相应操作{case1:/**************************************************************关闭串口前先将自动发送功能关闭***************************************************************/SetDlgItemText(IDC_BUTTON_AutoSend,"自动发送");//更改按键指示KillTimer(1);/**************************************************************///当前串口是打开的则进行关串口操作m_ctrlComm.SetPortOpen(FALSE);//关闭串口SetDlgItemText(IDC_BUTTON1,"打开串口");//更改按键指示UpdateData(FALSE);//更新按键状态break;case0://当前串口是关闭的则进行开串口操作m_ctrlComm.SetCommPort(1);//如果要打开串口则应先选择哪个串口m_ctrlComm.SetPortOpen(TRUE);//打开串口SetDlgItemText(IDC_BUTTON1,"关闭串口");//更改按键指示UpdateData(FALSE);break;default:AfxMessageBox("cannotopenorcloseserialport");}}else//串口的默认值有改变{switch(m_ctrlComm.GetPortOpen())//点击打开或关闭串口按键时,根据当前串口是否打开进行相应操作{case0://当前串口是关闭的则进行开串口操作m_ctrlComm.SetCommPort(m_Index+1);//如果要打开串口则应先选择哪个串口m_ctrlComm.SetPortOpen(TRUE);//打开串口SetDlgItemText(IDC_BUTTON1,"关闭串口");//更改按键指示UpdateData(FALSE);//更新按键状态break;case1:/**************************************************************关闭串口前先将自动发送功能关闭***************************************************************/SetDlgItemText(IDC_BUTTON_AutoSend,"自动发送");//更改按键指示KillTimer(1);/**************************************************************///当前串口是打开的则进行关串口操作m_ctrlComm.SetPortOpen(FALSE);SetDlgItemText(IDC_BUTTON1,"打开串口");UpdateData(FALSE);break;default:AfxMessageBox("cannotopenserialport");}}if(m_Index<0)((CComboBox*)GetDlgItem(IDC_COMBO_CommSelect))->SetCurSel(0);//如果没有另外进行串口选择则显示COM1if(m_BaudRate<0)((CComboBox*)GetDlgItem(IDC_COMBO_BaudRate_Select))->SetCurSel(0);//如果没有另外进行波特率选择则显示9600if(m_Date_Select<0)((CComboBox*)GetDlgItem(IDC_COMBO_Date_Select))->SetCurSel(0);////如果没有另外进行数据位选择则显示8if(m_StopBit<0)((CComboBox*)GetDlgItem(IDC_COMBO_StopBit))->SetCurSel(0);//如果没有另外进行停止位选择则显示1if(m_ParityCheck<0)((CComboBox*)GetDlgItem(IDC_COMBO_ParityCheck))->SetCurSel(0);//如果没有另外进行校验位选择则显示没有校验位N}10、添加自动发送功能:A、添加一个“编辑框”控件,此控件用于获取自动发送的时间间隔的,修改其ID为IDC_EDIT_Timer,为其添加一个value类UINT型变量m_TimerB、添加一个“按钮”控件,修改其ID为IDC_BUTTON_AutoSend修改其标题为“自动发送”C、添加一个“按钮”控件,修改其ID为IDC_BUTTON_StopAutoSend修改其标题为“停止自动发送”D、为“自动发送”按钮添加BN_CLICKED处理函数,程序代码如下:代码段9:voidCSCommTestDlg::OnBUTTONAutoSend(){UpdateData(TRUE);if(m_Timer<=0)//判断是否设置自动发送时间间隔AfxMessageBox("请设置自动发送时间间隔");elseif(!m_ctrlComm.GetPortOpen())//判断是否打开串口AfxMessageBox("请打开串口");else{SetDlgItemText(IDC_BUTTON_AutoSend,"自动发送...");//更改按键指示SetTimer(1,m_Timer,NULL);}}E、为“停止自动发送”按钮添加BN_CLICKED处理函数,程序代码如下:代码段9:voidCSCommTestDlg::OnBUTTONStopAutoSend(){//TODO:AddyourcontrolnotificationhandlercodehereSetDlgItemText(IDC_BUTTON_AutoSend,"自动发送");//更改按键指示KillTimer(1);}F、因为要设置自发送,所以要添加一个Windows定时函数,步骤如下:进入类向导,MessageMaps中的ObjectIDs中选择CScommTestDlg再选择Messages中的WM_TIMER,进入TIMER函数后,添加如下程序代码如下:代码段10:voidCSCommTestDlg::OnTimer(UINTnIDEvent){//TODO:Addyourmessagehandlercodehereand/orcalldefaultUpdateData(TRUE);if(m_ctrlHexSend.GetCheck()){CByteArrayhexdate;intlen=String2Hex(m_strTXData,hexdate);m_ctrlComm.SetOutput(COleVariant(hexdate));}elsem_ctrlComm.SetOutput(COleVariant(m_strTXData));CDialog::OnTimer(nIDEvent);}11、十六进制数据发送及接收显示添加一个“复选框”控件,修改ID为IDC_CHECK_HexSend,标题为“HEX发送”,进入类向导添加control类CButton型变量,变量名为m_ctrlHexSend,然后为为SCommTestDlg类添加以下两个PUBLIC成员函数,在Classview中右击CCommTestDlg选中AddMemberFunction…然后在函数类型中输入“int”,在函数描述中输入“String2Hex(CStringstr,CByteArray&senddate)”然后确定。编辑函数体如下:代码段11:intCSCommTestDlg::String2Hex(CStringstr,CByteArray&senddate){inthexdate,lowhexdate;inthexdatelen=0;intlen=str.GetLength();senddate.SetSize(len/2);for(inti=0;i=len)break;lstr=str[i];hexdate=ConvertHexChar(hstr);lowhexdate=ConvertHexChar(lstr);if((hexdate==16)||(lowhexdate==16))break;elsehexdate=hexdate*16+lowhexdate;i++;senddate[hexdatelen]=(char)hexdate;hexdatelen++;}senddate.SetSize(hexdatelen);returnhexdatelen;}再添加别一个CCommTestDlg添加两个成员函数,在函数类型中输入“char”,在函数描述中输入“ConvertHexChar(charch)”然后确定。编辑函数体如下:代码段12:charCSCommTestDlg::ConvertHexChar(charch){if((ch>='0')&&(ch<='9')){returnch-0x30;}elseif((ch>='A')&&(ch<='F')){returnch-'A'+10;}elseif((ch>='a')&&(ch<='f')){returnch-'a'+10;}elsereturn(-1);}再将CSCommTestDlg::OnButtonManualsend()修改成以下形式:代码段13:voidCSCommTestDlg::OnButtonManualsend(){//TODO:Addyourcontrolnotificationhandlercodehereif(!m_ctrlComm.GetPortOpen())//判断是否打开串口AfxMessageBox("请打开串口");else{UpdateData(TRUE);if(m_ctrlHexSend.GetCheck())//判断是否是自动发送{CByteArrayhexdate;intlen=String2Hex(m_strTXData,hexdate);m_ctrlComm.SetOutput(COleVariant(hexdate));}elsem_ctrlComm.SetOutput(COleVariant(m_strTXData));}}在接收框中以十六进制显示将代码段1,提示2的三句程序代码前的“//”去掉即可。至此,基本功能已完成,编译运行程序是否能实现各功能,如果出错,则细仔改正,再通过添加“组合框”控件或“静态文本”可以添加相应提示,再由菜单栏中的布局内的各种功能选择可以实现将各控件整齐排列效果如下:12、保存数据功能添加一个按钮控件,ID为IDC_BUTTON_SaveData,标题为:保存数据,添加两个“复选框”控件,一个ID为IDC_CHECK_HEXSave,标题为:HEX保存,另一个ID为IDC_CHECK_BCDSave,标题为:BCD保存,选择HEX保存则保存的数据为十六进制数据,选择BCD保存则保存的数据为十进制数据,但不可两都同时选择,再为两个复选框选添加两个control类CButton型变量,一个变量名为:m_HEXSave,另一个为m_BCDSave;为“保存数据”按钮添加一个BN_CLICKED函数;另外再为为SCommTestDlg类添加以下两个PUBLIC成员函数,此函数只要用于十六进制与十进制数据之间的转换,函数类型为CString,函数描述为HEX_To_BCD(CStringHexData),函数体如下:代码段13:再为“保存数据”按钮添,的BN_CLICKED函数添加函数体,代码如下:代码段14:13:清除数据:添加一个“清除数据”按钮控件,ID为IDC_BUTTON_CleanRXData,标题为:清空数据区,添加一个BN_CLICKED函数,函数体代码如下:代码段14:voidCSCommTestDlg::OnBUTTONCleanRXData(){//TODO:Addyourcontrolnotificationhandlercodeherem_strRXData.Empty();UpdateData(FALSE);}至此其串口调试助手其本功能已全部实现,编译程序运行后效果如下:
本文档为【VC6.0MFC串口通信编写全过程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
浩瀚天空
暂无简介~
格式:doc
大小:242KB
软件:Word
页数:16
分类:
上传时间:2022-02-09
浏览量:1