VCMSComm串口发送与接收上位机制做总结
运用VC++技术实现上位机与OMRON品牌PCL的串行通讯
运用VC++技术实现上位机与OMRON品牌PCL的串行通讯 林涛,张声兴 (梅里亚动物保健有限公司,上海 200031) 摘要:文章介绍了可编程控制器(PCL)与上位机(PC机)实现串行通信功能的硬件组成、通信协议,重点阐明在上位机(PC机)上基于 VC++6.0的编程实现细节,并进一步展望PLC对控制系统应用的前景。 关键词:可编程控制器(PCL);VC++
图3 命令格式 响应的格式与命令的格式相似,只是在识别码后面多了2个十六进制字符的结束码,用于返回命令的执行状态(有无错误及错误的原因)。例 如,命令帧为“@00RR00050002UV*CR”,表示计算机要求读出0号PLC中从CIO0005单元开始的2个单元的内容; 而PLC 的响应为 “@00RR0012345678XY*CR”,识别码后面的00为结束码,表示数据传送正确,其中十六进制数1234H、5678H分别为PLC给出的CIO中的 数据。一个帧最多由131个ACSⅡ字符组成,如果需要发送的字符超出131个,必须将数据分成若干个帧,第一帧和中间帧的结尾用分界符 (CR)代替结束符(*CR)。 2 VC++6.0软件实现 VC++6.0开发环境为串口通讯已经提供了ActiveX控件,名为MSComm控件。下面阐述对该控件属性的初始化设置以及相关实现代码。限 于篇幅,此文只将重要的实现代码罗列如下。 程序启动初始化设置代码如下: { My_Comm.SetCommPort(1);//选择 COM1口 My_Comm.SetSettings( 9600,E,7,1 );//设置通信参数 My_Comm.SetlnputMode(1);//设置二进制输入模式 My_Comm.SetInBufferSize(1024);//设置输入缓冲区大小 My_Comm.SetlnputLen(0);//使用Input将使MSComm控件读取接收缓冲区中的全部内容 My_Comm.SetOutBufferSize(1024);//设置输出缓冲区大小
自己用VB编制的上位机(MSComm控件)
自己用VB编制的上位机(MSComm控件)本人初学者,许多地方显得粗糙笨拙,但总算是成功了,不过自我感受VB真的很简单,我大致学了两三个星期就可以了。
本文只同向我一样的初学者分享一下经验,毕竟咱不是专业的。
下面开始。
上位机可方便地实现与单片机之间进行信息传递交互,能够更加容易对机械手臂进行控制,实现操作可视化,更加直观,保存重要数据等功能。
我们利用Visual Basic 6.0(以下简称VB)来编制上位机,VB 是一种功能强大、简单易学的程序设计语言。
它不但保留了原先Basic 语言的全部功能,而且还增加了面向对象程序设计功能。
它不仅可以方便快捷地编制适用于数据处理、多媒体等方面的程序,而且利用ActiveX控件MSComm还能十分方便地开发出使用计算机串口的计算机通信程序。
本实验涉及控制六路舵机,所以需要编制上位机实现一次向下位机传输含有六个数据的数组,同时接受来自下位机的数组,并显示。
整个过程可分为如下几个过程:一:VB是面向对象的语言,首先需要绘制程序界面该上位机大致分为左边的功能部分与右边的可视化调节部分。
功能部分有端口选择,用以选择合适的端口进行串口通信,波特率选择,打开与关闭端口,动作设置等。
为了便于布局,应用frame控件建立区域,再将控件拖到frame 区域中,对于功能相同的控件来说,建立控件组的方式会使编程避免重复繁琐,例如HScrollbar控件,先向frame区域内拖入一个HScrollbar控件,再复制,粘贴到frame区域内部,则提示是否建立控件组,点击确定即可。
这样便为后续编程带来很大的方便。
调节部分运用Hscrollbar控件来粗略调节度数,设定按钮与文本框配合来精确调节输出度数。
用右列文本框实时读取舵机当前角度。
用optionbutton控件来选择hscrollbar的步进精度,这里分为0.1度与1度两个不同的选项。
由于一组optionbutton中在程序运行中只能有一个处于选中状态,根据本程序要求,每一横列的两个optionbutton为一组,这样就需要frame控件,在同一个frame区域里的optionbutton默认为一组。
C#串口通信:MSComm控件使用详解
C#串口通信:MSComm控件使用详解目次MSComm 控件两种处理通讯的方式CommPort 属性RThreshold 属性CTSHolding 属性SThreshold 属性CDHolding 属性DSRHolding 属性Settings 属性InputLen 属性EOFEnable 属性Handshake 常数OnComm 常数InputMode 常数错误消息MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。
MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi 等语言中均可使用。
Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。
具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询法。
1.MSComm控件两种处理通讯的方式MSComm控件提供下列两种处理通讯的方式:事件驱动方式和查询方式。
1.1 事件驱动方式事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。
在许多情况下,在事件发生时需要得到通知,例如,在串口接收缓冲区中有字符,或者Carrier Detect (CD) 或Request To Send (RTS) 线上一个字符到达或一个变化发生时。
在这些情况下,可以利用MSComm 控件的OnComm 事件捕获并处理这些通讯事件。
OnComm 事件还可以检查和处理通讯错误。
所有通讯事件和通讯错误的列表,参阅CommEvent 属性。
在编程过程中,就可以在OnComm事件处理函数中加入自己的处理代码。
这种方法的优点是程序响应及时,可靠性高。
每个MSComm 控件对应着一个串行端口。
如果应用程序需要访问多个串行端口,必须使用多个MSComm 控件。
C#中串口组件的使用方法总结及上位机制作方法
public Form1() {
InitializeComponent();
} private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) {
这种方式是串口通信上位机制作的主要方式,其采用中断思想而成,当串口输入缓冲区中 的字节数据大于某个设定的个数时,触发串口输入中断,这时在中断程序中读取串口输入缓 冲区中的数据,具有实时性和灵活性,是个常用的较好的方法。本文也是采用这种方法来进 行串口输入缓冲区的实时数据读取。 (B)事件响应驱动下的串口输入缓冲区数据读取 .NET 中封装了 SerialPort 类 表示串行端口资源。 命名空间: System.IO.Ports 程序集: System(在 System.dll 中) 除了前面用到的串口常规属性设置(BuadRate,PortName),这里用到了一个新的串口属性:
ReadChar 从 SerialPort 输入缓冲区中同步读取一个字符。
ReadExistin 在编码的基础上,读取 SerialPort 对象的流和输入缓冲区中所有立即可用的字节。
g
ReadLine 一直读取到输入缓冲区中的 NewLine 值。
ReadTo 一直读取到输入缓冲区中的指定 value 的字符串。
使用方法见 C#中用 SerialPort 类中的 Write()方法发送十六进制数 1.为程序添加发送按钮,命名为 btn_send,为程序添加文本输入框 tb_send 2.在 btn_send 的回调函数中添加以下代码
vc串口通讯控件MSComm编程详解
vc串口通讯控件MSComm编程详解在mfc中进行串口通讯最简单的方法莫过于在对话框中使用MSCOMM控件了,MSComm 通信控件提供了一系列标准通信命令的接口,它允许建立串口连接,可以连接到其他通信设备(如Modem).还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工、事件驱动的、高效实用的通信程序。
一、用MSComm控件通信1.串口通信基础知识一般悦来,计算机都有一个或多个串行端口,它们依次为com1、Com2、…,这些串口还提供了外部设备与pC进行数据传输和皿信的通道。
这些串口在CPU和外设之间充当解释器的角色。
当字符数据从CPU发送给外设时,这些字符数据将被转换成串行比特流数据;当接收数据时,比特流数据被转换为字符数据传递给CPU,再进一步说,在操作系统方面,Windows用通信驱动程序(COMM.DRV)调用API函数发送和接收数据,当用通信控件或声明调用API函数时,它门由COMM. DRV解释并传递给设备驱动程序,作为一个vB程序员,要编写通信程序.只需知道通信控件提供给Windows通信AP1函数的接口即可.换句话说,只需设定和监视通信控件的属性和事件即可。
2.使用Mscomm控件在开始使用MSComm控件之前。
需要先了解其属性、事件或错误属性描述CommPort 设置或返回通信端口号Settings 以字符串的形式设置或返回波特率、奇偶校验、数据位和停止位PortOpen 设置或返回通信端口的状态。
也可以打开和关闭端口Input 返回和删除接收缓冲区中的字符Output 将字符串写入发送缓冲区CommEvent属性为通信事件或错误返回下列值之一。
在该控件的对象库中也可以找到这些常量。
常量值描述ComEventBreak 1001 收到了断开信号ComEventCTSTO 1002 Clear To Send Timeout。
手把手教你VC上位机MFC利用串口控件发送接收数据
1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest;2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。
选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。
(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX 一项选上,重新安装VC6,选上ActiveX就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。
3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #i nclude "mscomm.h"//}}AFX_INCLUDES 。
4.在对话框中添加控件向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。
VC++下用MSComm控件实现串口通讯
VC++下用MSComm控件实现串口通讯首先,在对话框中创建通信控件,若Control工具栏中缺少该控件,可通过菜单Project --> Add to Project --> Components and Control插入即可,再将该控件从工具箱中拉到对话框中。
此时,你只需要关心控件提供的对Windows 通讯驱动程序的API 函数的接口。
换句话说,只需要设置和监视MSComm控件的属性和事件。
打开所需串口后,需要考虑串口通信的时机。
在接收或发送数据过程中,可能需要监视并响应一些事件和错误,所以事件驱动是处理串行端口交互作用的一种非常有效的方法。
使用OnComm 事件和CommEvent 属性捕捉并检查通讯事件和错误的值。
发生通讯事件或错误时,将触发OnComm 事件,CommEvent 属性的值将被改变,应用程序检查CommEvent 属性值并作出相应的反应// 若是在SDI中使用该控件则要调用下两句,在对话框程序中该语句有MFC自己创建// 所以不用人为添加DWORD style=WS_VISIBLE;m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);// 串口控件的初始化DWORD style=WS_VISIBLE;m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);if(m_MSComm.GetPortOpen()) //如果串口是打开的,则行关闭串口{m_MSComm.SetPortOpen(FALSE);}m_MSComm.SetCommPort(1); //选择COM1m_MSComm.SetInBufferSize(1024); //接收缓冲区m_MSComm.SetOutBufferSize(1024);//发送缓冲区m_MSComm.SetInputLen(0);//设置当前接收区数据长度为0,表示全部读取m_MSComm.SetInputMode(1);//以二进制方式读写数据m_MSComm.SetRThreshold(1);//接收缓冲区有1个及1个以上字符时,将引发接收数据的OnComm事件m_MSComm.SetSettings("9600,n,8,1");//波特率9600无检验位,8个数据位,1个停止位if(!m_MSComm.GetPortOpen())//如果串口没有打开则打开m_MSComm.SetPortOpen(TRUE);//打开串口elsem_MSComm.SetOutBufferCount(0);// 控件事件的响应声明// *.h//{{AFX_MSG(CGolfView)afx_msg BOOL OnComm();DECLARE_EVENTSINK_MAP()//}}AFX_MSG// *.cppBEGIN_EVENTSINK_MAP(CGolfView, CView)//{{AFX_EVENTSINK_MAP(CAboutDlg)ON_EVENT(CGolfView, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE) //}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()// 控件事件的响应BOOL CGolfView::OnComm(){VARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata[2048]; //设置BYTE数组An 8-bit integerthat is not signed.CString strtemp;switch(m_MSComm.GetCommEvent()){case 1: // comEvSend发送数据break;case 2: // comEvReceive读取数据// MessageBox(_T("读取数据事件"), _T("TRACE"), MB_OK);variant_inp=m_MSComm.GetInput(); //读缓冲区safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量len=safearray_inp.GetOneDimSize(); //得到有效数据长度// 接受数据for(k=0; k<len; k++){safearray_inp.GetElement(&k,rxdata+k); //转换为BYTE型数组BYTE bt=*(char*)(rxdata+k); //字符型strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放recd+=strtemp;}// UpdateData(TRUE);break;default: // 传输事件出错m_MSComm.SetOutBufferCount(0);break;}UpdateData(FALSE); //更新图象内容return TRUE;}核心代码初始化函数BOOL CSCommTestDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu. made by lzycsd// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTB OX, strAboutMenu); }}// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization here////////////////////////////////////////////////////其他初始化m_ctrlComboComPort.SetCurSel(0); //初始选择串口1m_ctrlComboBaudRate.SetCurSel(6); //初始选择波特率9600m_ctrlComboParityBit.SetCurSel(0); //初始选择校验位无m_ctrlComboDataBit.SetCurSel(3); //初始选择数据位8位m_ctrlComboStopBit.SetCurSel(0); //初始选择停止位1位m_strSendPeriod="1000"; //初始自动发送周期为1000毫秒UpdateData(FALSE); //修改编辑框内容//GetDlgItem(IDC_EDIT_SENDPERIOD)->SetWindowText("1000");另一种方法设置////其他初始化//////////////////////////////////////////////////串口初始化m_ctrlComm.SetCommPort(m_ctrlComboComPort.GetCurSel()+1); //选择COM1//波特率9600,无校验,8个数据位,1个停止位m_ctrlComm.SetInputMode(1); //输入方式为二进制方式m_ctrlComm.SetInBufferSize(1024); //设置输入缓冲区大小m_ctrlComm.SetOutBufferSize(512); //设置输出缓冲区大小//波特率9600,无校验,8个数据位,1个停止位m_ctrlComm.SetSettings("9600,N,8,1");if(!m_ctrlComm.GetPortOpen())// {m_ctrlComm.SetPortOpen(TRUE); //打开串口SetPortOpen函数返回值为void// m_ctrlOpenCom.EnableWindow(FALSE); //使按钮变灰//if (!m_ctrlComm.GetPortOpen())// 如果串口已经打开(打开串口失败),会走到这里来,加上你的判断就可以了……// AfxMessageBox("没有发现此串口或被其他程序占用");//m_ctrlCloseCom.EnableWindow(FALSE); //打开串口失败// m_ctrlOpenCom.EnableWindow(TRUE);// }// else// {// m_ctrlOpenCom.EnableWindow(FALSE);// }m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接受缓冲区中有多于或等于1个字符时将引发一个接受数据的OnComm事件m_ctrlComm.SetInputLen(0); //设置当前接受区数据长度为0m_ctrlComm.GetInput(); //先预读缓冲区以清除残留数据m_bSerialPortOpened=TRUE; //串口成功打开m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮失效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮有效return TRUE; // return TRUE unless you set the focus to a control}从串口接受数据并显示在接受编辑框中static long rxdatacount=0; //接受字符计数void CSCommTestDlg::OnComm(){// TODO: Add your control notification handler code hereVARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata[2048]; //设置BYTE数组CString strtemp;if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接受缓冲区内有字符{variant_inp=m_ctrlComm.GetInput(); //读缓冲区safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量len=safearray_inp.GetOneDimSize(); //得到有效数据长度for(k=0;k<len;k++)safearray_inp.GetElement(&k,rxdata+k); //转换为BYTE型数组for(k=0;k<len;k++) //将数组转换为Cstring型变量{BYTE bt=*(char*)(rxdata+k); //字符型strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放m_strEditRXData+=strtemp; //加入接受编辑框对应字符串//////////////////////////////////////////////////////放在这里计数会卡//rxdatacount++; //接受的字节计数//CString temp;//temp.Format("%ld",rxdatacount);//temp="接受:"+temp;//m_ctrlRXCount.SetWindowText(temp); //显示接受计数////////////////////////////////////////////////////}rxdatacount+=len;//m_ctrlRXCount.SetWindowText("接受:"+rxdatacount);CString temp;temp.Format("%ld",rxdatacount);temp="接受:"+temp;m_ctrlRXCount.SetWindowText(temp); //显示接受计数}UpdateData(FALSE); //更新编辑框内容}点击发送按钮处理函数//手工发送数据long TX_count=0;void CSCommTestDlg::OnButtonManualsend(){// TODO: Add your control notification handler code hereUpdateData(TRUE); //读取编辑框内容m_ctrlComm.SetOutput(COleVariant(m_strEditTXData)); //发送数据X_count+=m_strEditTXData.GetLength(); //发送计数CString strTemp;strTemp.Format("发送:%d",TX_count);m_ctrlTXCount.SetWindowText(strTemp); //显示计数GetDlgItem(IDC_BUTTON_MANUALSEND)->EnableWindow(TRUE);}void CSCommTestDlg::OnEditchangeComboComport(){// TODO: Add your control notification handler code here}改变串口时的处理函数void CSCommTestDlg::OnSelchangeComboComport(){// TODO: Add your control notification handler code here//int Cpos=m_ctrlComboComPort.GetCurSel()+1; //获取当前选择的串口号//测试用//CString myString ;//myString.Format("%d",Cpos);//CWnd* pWnd = GetDlgItem(IDC_STATIC1);//pWnd->SetWindowText(_T(myString));//测试用//if(m_ctrlComm)if(m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(FALSE); //关闭串口m_bSerialPortOpened=FALSE; //串口成功关闭m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮有效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮失效}//打开串口//选择相应的波特率,校验位,数据位,停止位m_ctrlComm.SetCommPort(m_ctrlComboComPort.GetCurSel()+1);//选择相应的COMm_ctrlComm.SetInputMode(1); //输入方式为二进制方式m_ctrlComm.SetInBufferSize(1024);//设置输入缓冲区大小m_ctrlComm.SetOutBufferSize(512); //设置输出缓冲区大小//选择相应的波特率,校验位,数据位,停止位CString setstr;CString tempstr;m_ctrlComboBaudRate.GetWindowText(tempstr); //获取波特率setstr=tempstr;setstr+=",";m_ctrlComboParityBit.GetWindowText(tempstr); //获取校验位tempstr=tempstr.Left(1); //取第一个单词setstr=setstr+tempstr+",";m_ctrlComboDataBit.GetWindowText(tempstr); //获取数据位setstr=setstr+tempstr+",";m_ctrlComboStopBit.GetWindowText(tempstr); //获取停止位setstr+=tempstr;/*int BaudRate = 9600;char ParityBit = n;int DataBit = 8;int StopBit = 1;setstr.Format( "%d,%c,%d,%d ",BaudRate,ParityBit,DataBite,StopBit);SetSettings(setstr);*///m_ctrlComm.SetSettings("9600,N,8,1");m_ctrlComm.SetSettings(setstr);if(!m_ctrlComm.GetPortOpen())m_ctrlComm.SetPortOpen(TRUE); //打开串口m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接受缓冲区中有多于或等于1个字符时将引发一个接受数据的OnComm事件m_ctrlComm.SetInputLen(0); //设置当前接受区数据长度为0m_ctrlComm.GetInput(); //先预读缓冲区以清除残留数据m_bSerialPortOpened=TRUE; //串口成功打开m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮失效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮有效}打开串口void CSCommTestDlg::OnButtonOpen(){// TODO: Add your control notification handler code hereif(!m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(TRUE);m_bSerialPortOpened=TRUE; //串口成功打开m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮失效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮有效}}关闭串口void CSCommTestDlg::OnButtonClose(){// TODO: Add your control notification handler code hereif(m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(FALSE);m_bSerialPortOpened=FALSE; //串口成功关闭m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮有效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮失效}}定时器触发后运行的函数void CSCommTestDlg::OnTimer(UINT nIDEvent){// TODO: Add your message handler code here and/or call default//添加你要处理的函数,当定时时间到时自动调用//通过调用SetTimer(1,1000,NULL)启动定时器,通过调用KillTimer(int nIDEvent)关闭定时器OnButtonManualsend();CDialog::OnTimer(nIDEvent);}选择自动发送触发的函数void CSCommTestDlg::OnCheckAutosend(){// TODO: Add your control notification handler code hereif(m_ctrlAutoSend.GetCheck()){ //自动发送int i=atoi(m_strSendPeriod);SetTimer(1,i,NULL);//函数反回值就是第一个参数值1,表示此定时器的ID号。
基于VC++和MFC的上位机与PLC的通讯系统
要:本文介绍了用VC++和MFC开发的上位机和PLC的通讯系统,给出了系统的通讯原理和系统的软件设计方法。
实践证明整个系统运行稳定,实用性和可扩展性强。
关键词:PLC;VC++;MFC;通讯模式1 概述PLC(Programmable Logic Controller)作为新一代工业控制器,以其高性能价格比在工业测控系统中获得了广泛应用。
随着微电子及控制技术的不断发展,PLC已逐渐成为一种智能型、综合型控制器,由PLC 构成的集散控制是现代工业控制的一个重要组成部分。
在众多的小型集散控制系统中,若使用专业工控组态软件,如INTOUCH、FIX等,制作上位机的监控界面,而以专用的PLC通信接口模块以及其厂家推荐的DDE Server作为联系上位机和PLC的桥梁,则成本较高、投资较大。
所以上位机直接与PLC的通讯是一种很好的技术方案。
在Windows环境下开发与工业PLC通讯,可以利用C并借助Windows SDK提供的应用程序接口函数来完成软件的设计,但这样开发的程序很复杂;也可以利用Visual Basic提供的通讯控件来开发串行通讯程序,程序的编制十分简单,但在现实中,许多大的应用系统都是基于VC++平台开发的,VC++是现今最复杂、但也是最强大的一种Windows应用程序开发工程软件。
它在图形处理和数据库管理等方面具有较强的优势,并且用它来实现底层的通讯控制有着更快的效率,使用MFC设计的界面与Visual Basic设计的界面一样简练。
因此我们利用VC++6.0提供的通讯控件MSComm,以MFC来设计界面编制程序,构造与PLC的通讯系统。
系统中的PLC为西门子公司的S7-200系列CPU226型。
2 系统的通讯原理西门子S7-226型PLC是一种模块化结构的小型PLC,具有较高的性能价格比,它带有两个RS485通讯口,而上位机即工控机的串行口是RS232,所以采用西门子公司专用的PC/PPI编程电缆作为上下位机的连接电缆,它实现了RS232和RS485的转换,并且具有隔离抗干扰功能。
串口编程中使用MScommd的注意事项
串口编程中使用MScommd的注意事项串口编程中使用MScommd的注意事项微机能否通过端口检测到电平信号?悬赏分:20 - 解决时间:2006-10-16 11:39我做一个控制系统,需要微机检测到外部发出的信号(比如一个高电初次接触mysql:c++ 连接mysqlC语言链接MySQL, (实例一)用的是mysql自带的LIB包。
#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <mysql.h>MYSQL* my_conn(){MYSQL *mysql;/*初始化指针*/mysql = mysql_init(NULL);/*连接数据库*/if(!(mysql = mysql_real_connect(mysql, "localhost", "root", "root", "test", 0, NULL, 0))){printf("error!!%s\n", mysql_error(mysql));exit(1);}printf("连接数据库成功!!\n");return mysql;}/*执行sql语句并返回*/MYSQL_RES* execute_query(MYSQL* mysql, char *sql){MYSQL_RES *res = NULL;printf("sql:%s\n", sql);/*执行SQL语句*/if(mysql_query(mysql,sql)) {fprintf(stderr,"Query failed (%s)\n",mysql_error(mysql));exit(1);}/*返回结果集*/if (!(res=mysql_store_result(mysql))) {fprintf(stderr,"Couldn't get result from %s\n", mysql_error(mysql));exit(1);}/*结果列数*/printf("number of fields returned: %d\n",mysql_num_fields(res));return res;}int main(){MYSQL *mysql;MYSQL_RES *res;MYSQL_ROW row;char *qbuf;mysql = my_conn();qbuf = "select * from test";/* printf("main sql:%s\n", qbuf);*/ res = execute_query(mysql, qbuf);while(row = mysql_fetch_row(res)) {printf("id=%s\t", row[0]);printf("name=%s\t", row[1]);printf("remark=%s\n", row[3]);}puts("query ok!!\n");mysql_free_result(res);mysql_close(mysql);return 1;}C语言链接MYSQL数据库(实例二1#include <mysql.h>/*注意要包含这个头文件*/2#include <string.h>3#include <stdlib.h>4#include <stdio.h>56/*定义了一些数据库连接需要的宏*/7#define HOST "localhost"8#define USERNAME "ABitNo"9#define PASSWORD "ABitNo"10#define DATABASE "abitno"1112/*这个函数用来执行传入的sql語句*/13void exe_sql(char* sql) {1415 MYSQL my_connection; /*这是一个数据库连接*/16int res; /*执行sql語句后的返回标志*/1718/*初始化mysql连接my_connection*/19 mysql_init(&my_connection);2021/*这里就是用了mysql.h里的一个函数,用我们之前定义的那些宏建立mysql连接,并22返回一个值,返回不为空证明连接是成功的*/23if (mysql_real_connect(&my_connection, HOST, USERNA ME, PASSWORD, DATABASE,24 0, NULL, CLIENT_FOUND_ROWS)) {/*连接成功*/2526 printf("数据库执行exe_sql连接成功!\n");2728/*这句话是设置查询编码为utf8,这样支持中文*/29 mysql_query(&my_connection, "set names utf8");3031/*下面这句话就是用mysql_query函数来执行我们刚刚传入的sql語句,32这会返回一个int值,如果为0,证明語句执行成功*/33 res = mysql_query(&my_connection, sql);3435if (res) {/*现在就代表执行失败了*/36 printf("Error: mysql_query !\n");37/*不要忘了关闭连接*/38 mysql_close(&my_connection);39 } else {/*现在就代表执行成功了*/40/*mysql_affected_rows会返回执行sql后影响的行数*/41 printf("%d 行受到影响!\n\n", mysql_affected_rows(&my_connection));42/*不要忘了关闭连接*/43 mysql_close(&my_connection);44 }4546 } else {47/*数据库连接失败*/48 printf("数据库执行exe_sql连接失败!\n");49 }50}5152/*这个函数用来执行传入的sql語句,并打印出查询結果*/53void query_sql(char* sql) {54 MYSQL my_connection; /*这是一个数据库连接*/55int res; /*执行sql語句后的返回标志*/56 MYSQL_RES *res_ptr; /*指向查询结果的指针*/57 MYSQL_FIELD *field; /*字段结构指针*/58 MYSQL_ROW result_row; /*按行返回的查询信息*/5960int row, column; /*查询返回的行数和列数*/61int i, j; /*只是控制循环的两个变量*/6263/*初始化mysql连接my_connection*/64 mysql_init(&my_connection);6566/*这里就是用了mysql.h里的一个函数,用我们之前定义的那些宏建立mysql连接,并67返回一个值,返回不为空证明连接是成功的*/68if (mysql_real_connect(&my_connection, HOST, USERNA ME, PASSWORD, DATABASE,69 0, NULL, CLIENT_FOUND_ROWS)) {/*Connection suc cess*/7071 printf("数据库查询query_sql连接成功!\n");7273/*这句话是设置查询编码为utf8,这样支持中文*/74 mysql_query(&my_connection, "set names utf8");7576/*下面这句话就是用mysql_query函数来执行我们刚刚传入的sql語句,77这会返回一个int值,如果为0,证明語句执行成功*/78 res = mysql_query(&my_connection, sql);7980if (res) { /*现在就代表执行失败了*/81 printf("Error: mysql_query !\n");82/*不要忘了关闭连接*/83 mysql_close(&my_connection);84 } else { /*现在就代表执行成功了*/85/*将查询的結果给res_ptr*/86 res_ptr = mysql_store_result(&my_connection);8788/*如果结果不为空,就把结果print*/89if (res_ptr) {90/*取得結果的行数和*/91 column = mysql_num_fields(res_ptr);92 row = mysql_num_rows(res_ptr) + 1;93 printf("查询到 %lu 行 \n", row);9495/*输出結果的字段名*/96for (i = 0; field = mysql_fetch_field(res_ptr); i++)97 printf("%s\t", field->name);98 printf("\n");100/*按行输出結果*/101for (i = 1; i < row; i++) {102 result_row = mysql_fetch_row(res_ptr); 103for (j = 0; j < column; j++)104 printf("%s\t", result_row[j]);105 printf("\n");106 }107108 }109110/*不要忘了关闭连接*/111 mysql_close(&my_connection);112 }113 }114}115116int main(int argc, char *argv[]) {117/*测试下向里面插入数据*/118char *exe = "insert into abitno values('ABitNo','');"; 119 exe_sql(exe);120121/*测试下查询*/122char *query = "select * from abitno;";123 query_sql(query);124125return 0;C语言链接MYSQL数据库(实例三)对于刚刚接触MySQL的用户,如果想用C语言连接MySQL,往往会是一件很麻烦的事情。
在VS(VC)2010中使用MSComm控件实现串口通信的详细步骤
// TODO: 在¨²此ä?添¬¨ª加¨®控?件t通ª¡§知a处ä|理¤¨ª程¨¬序¨°代䨲码? }
void CCommTestDlg::OnBnClickedButtonOpen() { // TODO: 在¨²此ä?添¬¨ª加¨®控?件t通ª¡§知a处ä|理¤¨ª程¨¬序¨°代䨲码? }
10. 添加关闭串口按钮的消息响应函数 void CCommTestDlg::OnBnClickedButtonClose() { // TODO: 在此添加控件通知处理程序代码 m_mscomm.put_PortOpen(FALSE);//关闭串口 AfxMessageBox(_T("串口 1 已关闭")); } 11. 添加发送按钮消息响应函数 void CCommTestDlg::OnBnClickedButtonSend() { // TODO: 在此添加控件通知处理程序代码 UpdateData(true); //读取编辑框内容 m_mscomm.put_Output(COleVariant(m_EditSend));//发送数据 m_EditSend.Empty(); //发送后清空输入框 UpdateData(false); //更新编辑框内容 } 12. 接收数据 void CCommTestDlg::OnCommMscomm1() { // TODO: 在此处添加消息处理程序代码 static unsigned int cnt=0; VARIANT variant_inp; COleSafeArray safearray_inp; long len,k; unsigned int data[1024]={0}; byte rxdata[1024]; //设置 BYTE 数组 CString strtemp; if(m_mscomm.get_CommEvent()==2) //值为 2 表示接收缓冲区内有字符 {
VC基于MSCOMM控件串口通讯
VC基于MSCOMM控件串口通讯在mfc中进行串口通讯最简单的方法莫过于在对话框中使用MSCOMM控件了,MSComm通信控件提供了一系列标准通信命令的接口,它允许建立串口连接,可以连接到其他通信设备(如Modem).还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工、事件驱动的、高效实用的通信程序。
一、用MSComm控件通信1.串口通信基础知识一般悦来,计算机都有一个或多个串行端口,它们依次为com1、Com2、…,这些串口还提供了外部设备与pC进行数据传输和皿信的通道。
这些串口在CPU和外设之间充当解释器的角色。
当字符数据从CPU 发送给外设时,这些字符数据将被转换成串行比特流数据;当接收数据时,比特流数据被转换为字符数据传递给CPU,再进一步说,在操作系统方面,Windows用通信驱动程序(COMM.DRV)调用API函数发送和接收数据,当用通信控件或声明调用API函数时,它门由COMM. DRV解释并传递给设备驱动程序,作为一个vB程序员,要编写通信程序.只需知道通信控件提供给Windows通信AP1函数的接口即可.换句话说,只需设定和监视通信控件的属性和事件即可。
2.使用Mscomm控件在开始使用MSComm控件之前。
需要先了解其属性、事件或错误属性描述CommPort 设置或返回通信端口号Settings 以字符串的形式设置或返回波特率、奇偶校验、数据位和停止位PortOpen 设置或返回通信端口的状态。
也可以打开和关闭端口Input 返回和删除接收缓冲区中的字符Output 将字符串写入发送缓冲区CommEvent属性为通信事件或错误返回下列值之一。
在该控件的对象库中也可以找到这些常量。
常量值描述ComEventBreak 1001 收到了断开信号ComEventCTSTO 1002 Clear To Send Timeout。
在发送字符时,在系统指定的事1件内,CTS(Clear To Send)线是低电平ComEventDSRTO 1003 Data Set Ready Timeout。
MSComm控件使用总结
MSComm控件在VS2010和VC6++中是不同的,下面以VS2010中为例,说明该控件的使用:1、打开串口,并初始化void CSMommTestDlg::OnBnClickedBtn(){// TODO: 在此添加控件通知处理程序代码if (m_Comm.get_PortOpen())//如果发现串口原来是打开的,关闭串口m_Comm.put_PortOpen(FALSE);m_Comm.put_CommPort(1);//选择COM1端口m_Comm.put_InBufferSize(1024);//设置输入缓冲区大小m_Comm.put_OutBufferSize(512);//设置输出缓冲区大小m_Comm.put_Settings("9600,n,8,1");//设置波特率9600,无校验,8个数据位,1个停止位if (!m_Comm.get_PortOpen()){m_Comm.put_PortOpen(TRUE);//打开串口m_Comm.put_RThreshold(1);//每当接收缓冲区中有1个字符,则接收串口数据m_Comm.put_InputLen(0);//设置当前缓冲区长度为0m_Comm.get_Input();//预读缓冲区以清除残留数据}else{AfxMessageBox("打开端口失败!");}}2、OnComm事件处理,当接受到信息的时候会触发这一事件void CSMommTestDlg::OnCommMscomm(){// TODO: 在此处添加消息处理程序代码VARIANT variant_inp;COleSafeArray safearray_inp;CString strInput;if (m_Comm.get_CommEvent()==2)//值为2表示接收缓冲区内有字符{variant_inp=m_Comm.get_Input();//读取缓冲区消息strInput=variant_inp.bstrVal;SetDlgItemText(IDC_EDIT_RECV,strInput);}}3、发送消息void CSMommTestDlg::OnSendClickedBtn(){// TODO: 在此添加控件通知处理程序代码CString str;GetDlgItemText(IDC_EDIT_SEND,str);m_Comm.put_Output(COleVariant(str));//发送数据}。
vc++_串口上位机编程实例 附vc串口通信(接收)
VC++串口上位机简单例程(源码及详细步骤)VC++编写简单串口上位机程序串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。
编译环境:VC++6.0操作系统:VMWare虚拟出来的Windows XP程序实现功能:1、PC初始化COM1口,使用n81方式,波特率57600与单片机通信。
PC的COM口编号可以通过如下方式修改:当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。
COM1口可用的话,会提示串口初始化完毕。
否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。
2、点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa后启动ADC 转换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC进行数值转换后在窗口里显示。
(见文章末尾图)3、为防止串口被一只占用,点击关闭串口可以关闭COM1,供其它程序使用,点击后按钮变为打开串口,点击可重新打开COM1。
程序的编写:1、打开VC++6.0建立基于对话框的MFC应用程序Test,2、在项目中插入MSComm控件:工程->增加到工程->Components and Controls->双击Registered ActiveX Controls->选择Microsoft Communications Control, version 6.0->Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。
串口传输实验总结
串口传输实验总结引言串口通信是一种常见的数据传输方式,特别适用于嵌入式系统和电子设备之间的通信。
在本次实验中,我们通过使用串口通信来实现数据的传输和接收。
本文档将总结我们在这个实验中的经验和教训,并提供一些关于串口传输的相关知识。
实验背景串口,也被称为通用异步收发传输器(UART),是一种用于在电子设备之间传输数据的常见接口。
串口通信使用两根线来传输数据,一根用于发送数据(Tx)而另一根用于接收数据(Rx)。
串口通信的一个重要特点是它是异步的,即发送端和接收端可以根据各自的节奏进行数据传输。
实验过程我们在本次实验中使用了一块嵌入式开发板和计算机之间的串口通信来实现数据传输。
以下是我们完成实验的步骤:1.配置串口通信参数:我们首先需要确定串口通信的参数,例如波特率、数据位、停止位和校验位等。
这些参数需要在发送端和接收端进行一致配置,以确保正常的数据传输。
2.编写发送端代码:我们使用编程语言编写了一个简单的程序,通过串口发送数据给接收端。
在这个程序中,我们首先初始化串口,然后将要发送的数据写入串口缓冲区,最后启动数据传输。
3.编写接收端代码:我们同样使用编程语言编写了一个程序,用于接收来自发送端的数据。
在这个程序中,我们首先初始化串口,然后开启中断监听串口接收事件,当接收到数据时,触发相应的中断处理函数来处理接收到的数据。
4.运行程序并进行测试:我们将发送端和接收端的代码分别烧录到嵌入式开发板和计算机上,并运行程序进行测试。
我们发送了不同类型的数据,例如字节、字符串和数字等,并检查接收端是否成功接收到并正确处理这些数据。
实验结果在我们的实验中,我们成功地实现了串口数据的传输和接收。
我们发送的各种类型的数据都能够被接收端正确地接收到并进行处理。
通过对输出结果的检查,我们确认了数据的准确性和完整性。
实验总结通过这个实验,我们深入了解了串口通信的原理和应用。
以下是我们在实验中的一些总结和教训:1.注意配置参数的一致性:在串口通信中,发送端和接收端的串口配置参数必须一致,包括波特率、数据位、停止位和校验位。
MSComm控件实现串口通信的方法
MSComm控件实现串口通信的方法碧峰晨曦摘要:详细介绍了MSComm控件,并在VC++6.0中利用MSComm控件开发了基于对话框的串口通信实例。
关键词:串口通信,MSComm,VC++图书编号:TP3110.引言串口通信具有实现简单、价格低廉、通信稳定、数据传输可靠等优点,因而广泛应用于各种工业控制系统中。
MSComm控件是微软公司开发的专门用于串口通信的控件。
该控件为开发串口通信程序提供了更加快捷、容易的方法。
在VC++中,对控件属性的操作都是通过特定的函数来实现的,这些函数都是CMSComm类的成员函数。
当声明了一个CMSComm类对象后,就可以通过如下格式调用成员函数来访问控件属性了:<对象名>.<成员函数名>(<参数表>)或<对象名>-><成员函数名>(<参数表>)1.MSComm控件属性及事件1.1 MSComm控件属性MSComm控件有许多属性,最主要的几个属性如下:1)CommPort:设置该属性值可以获取当前程序使用的串口编号。
2)Setting:设置或者获取串行通信的通信参数(包括波特率、奇偶校验类型、数据位数及停止位数等)。
3)PortOpen:设置该属性可以打开或关闭串口。
4)Input:从接收缓冲区中返回并删除数据。
5)Output:向串口通信输出缓冲区写入数据。
6)CommEvent:当MSComm控件在运行时发生错误或产生各种事件时,向程序返回错误或事件类型。
1.2 MSComm控件的事件该控件只有一个事件,即OnComm事件。
当CommEvent属性值发生变化时就会触发OnComm事件。
根据CommEvent属性值来分别执行各种情况下的处理程序。
2 MSComm控件实例应用2.1插入MSComm控件在VC++6.0中新建一个基于对话框的工程,命名为Test。
默认情况下,VC++6.0中不会包含MSComm控件,所以需要我们手动将MSComm控件加载到VC++6.0中。
VC++MSComm串口发送与接收上位机制做总结
VC++MSComm串口发送与接收上位机本设计用VC编写的一个简单的上位机软件,实现功能为:简单的串口数据发送与接收。
具体步骤如下:一.建立应用程序工程“串口通信_韩季方01”1.打开VC++6.0-》建立对话框MFC应用程序:串口通信_韩季方01—》添加基本控件如图1。
0.图1。
02.添加MSComm控件:Add To Project—》Components and Controls…打开如图1.1,双击“Registered ActiveX Contronls”项—》出现如图1.2—》选择“Microsoft Communications Control,version 6。
0"控件—》点击“Insert”—》提示“…”确认即可-》弹出图1.3—》点击“OK”—》再点击“Close”。
下一步,将对话框资源控件中的电话状控件托到对话框中即可,如图1.4。
图1。
1 图1。
2图1.3图1.4 3。
编辑控件及其属性设置:如表1。
0控件控件ID Caption 需要添加的变量及变量类型静态文本IDC_STATIC 接收显示静态文本IDC_STATIC 发送输入编辑框IDC_EDIT_RXDATA m_strEditRXDataValue CString编辑框IDC_EDIT_TXDATA m_strEditTXDataValue CString 按键IDC_BUTTON_MANUALSEND 发送IDC_MSCOMM1 m_ctrlcomm control MSComm控件表1.04。
添加变量及其类型方法如图1.5图1.5二.初始化串口:设置MSComm控件属性打开Class Wizard—》Member Variables-》选IDC_MSCOMM1-》点击“Add Varialbe…"—》添加变量m_ctrlComm。
如图1。
5。
之后,在工作空间打开文件如图2。
0—》在函数OnInitDialog中添加代码如图2.1.图2.0图2。
VC中应用MSComm控件实现串口通信
VC中应用MSComm控件实现串口通信
王正强
【期刊名称】《电子测试》
【年(卷),期】2010(000)005
【摘要】串行通信作为一种灵活、方便、可靠的通信方式.广泛应用于计算机与其他设备之间的通信以及工业控制系统中,是计算机与外部设备进行数据通信时经常使用的方式之一.本文介绍了MSComm控件实现串口通信的基础知识,并且研究了利用MSComm控件实现串口通信的关键技术问题,指出MSComm控件实现PC 间串口通信的一般步骤,在VC++6.0环境下利用MSComm实现PC与PC之间的串口通信,最后通过一个实例给出了MSComm控件在VC++6.0串口通信中的应用.无论在工业控制中PC和单片机之间的通信,还是在2台PC之间的串口通信,都具有相同的原理.只要掌握其中的通信本质,就能灵活地实现串口通信,串口控制.【总页数】4页(P73-76)
【作者】王正强
【作者单位】中北大学信息探测与处理技术研究所,太原,030051
【正文语种】中文
【中图分类】TP311.5
【相关文献】
1.MScomm控件在VC++6.0串口通信中的应用 [J], 王华;岳丽全;岳志高
2.C++builder5中基于MSComm控件串口通信的编程与实现 [J], 罗日成;李卫
国
3.VC6.0下应用MSComm控件实现RS485串行通讯 [J], 李庆华;姜会文;邱书波
4.基于MSComm控件的串口通信在CVD控制装置中的应用 [J], 苏卫峰;李霞;单正娅
5.MSComm控件在开发GPS接收板串口通信程序中的应用 [J], 余衡;王仲东因版权原因,仅展示原文概要,查看原文内容请购买。
mscomm控件总结
有些博客乱七八糟的各种打开COM然后一堆繁琐的注册,我想说一句简单的命令就可以了,如下:Windows打开运行,并注册mscomm32.ocx文件,代码如下:regsvr32 c:\windows\SysWOW64\MSCOMM32.OCXWindows+r调出运行,输入regedit转到注册表中,如下:找到HEKY_CLASSES_ROOT项下的License项,新建主键为4250E830-6AC2-11cf-8ADB-00AA00C00905,键值为kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun的项目,如下所示(特别注意,不新建或者主键、键值出现错误,VS添加MSCOMM后还是没法找到COM控件的)。
注意这里主键和键值一个都不能错,否则VS2010添加MSCOMM控件后,还是会找不到这个控件。
我以身试法,崩溃过,因为键值缺了一个最后的5.VS2010工具箱中添加COM组件反应的确超级慢,真的要等一会会儿,然后跳出选择工具箱项,从COM组件中浏览,如下所示:此时在对话框中右键单击,添加Acticve控件,将会出现Microsoft Communications Control, version 6.0控件。
我拖人实现的原来的工程也可以开开心心的打开了啦啦啦。
MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。
MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。
Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。
具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询法。
通过MSComm控件进行WINCC串口通讯总结
通过MSComm控件进行WINCC串口通讯总结目的:通过MSComm控件实现WINCC串口通讯(C脚本和VB脚本两种方式)测试环境:操作系统win7WINCC版本:V7.2帮助工具:串口调试工具ASPD虚拟串口工具测试WINCC组态画面:测试试验过程画面:1、通过VB实现串口通讯画面对象“打开画面”VB大事脚本:Sub OnOpen()Dim objMSComm, tagConnectionSet objMSComm = hmiRuntime.Screens("串口通讯VB版").ScreenItems("COM")Set tagConnection = HMIRuntime.Tags("tagConnection1")If objMSComm.PortOpen = False Then' Assign com port numbermport = 4objMSComm.Settings = "9600,N,8,1"objMSComm.RThreshold = 1objMSComm.SThreshold = 0objMSComm.InBufferCount = 0objMSComm.InputLen = 0objMSComm.PortOpen = TruetagConnection.Write (True)HMIRuntime.Trace("Port open." vbCrLf)ElseHMIRuntime.Trace("Port is already opened." vbCrLf)End IfEnd SubMSComm控件OnComm对象大事:Sub OnOpen()Dim objMSComm, tagConnectionSet objMSComm = HMIRuntime.Screens("串口通讯VB版").ScreenItems("COM")Set tagConnection = HMIRuntime.Tags("tagConnection1")If objMSComm.PortOpen = False Then' Assign com port numbermport = 4objMSComm.Settings = "9600,N,8,1"objMSComm.RThreshold = 1objMSComm.SThreshold = 0objMSComm.InBufferCount = 0objMSComm.InputLen = 0objMSComm.PortOpen = TruetagConnection.Write (True)HMIRuntime.Trace("Port open." vbCrLf)ElseHMIRuntime.Trace("Port is already opened." vbCrLf)End IfEnd Sub“SEND按钮”鼠标左键按下大事:Sub OnLButtonDown(ByVal Item, ByVal Flags, ByVal x, ByVal y)Dim objMSCommDim strTemp,bufferHMIRuntime.Trace("Communication!" vbCrLf)Set objMsComm = HMIRuntime.Screens("串口通讯VB版").ScreenItems("COM")Set buffer = HMIRuntime.Tags("Buffer1")strTemp = buffer.ReadIf objMSComm.PortOpen = True ThenIf strTemp"" thenobjMSComm.Output=strTempEnd IfEnd IfEnd Sub2、通过C脚本实现串口通讯画面对象“打开画面”C大事脚本:#include "apdefap.h"void OnOpenPicture(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName){#define GetObject GetObject__object *pdl=NULL;__object *pic=NULL;__object *obj=NULL;int i,j;pdl = __object_create("PDLRuntime");if(pdl){printf("portopen get pdl ok ");}pic=pdl-GetPicture("串口通讯C版"); if(pic){printf("portopen get pic ok ");}obj=pic-GetObject("COM");if(obj){printf("portopen get obj ok ");}if(obj-PortOpen==0){obj-Commport = 3;obj-Settings = "9600,N,8,1";obj-RThreshold = 1;obj-SThreshold = 0;obj-InBufferCount = 0;obj-InputLen = 0;obj-PortOpen = 1;}__object_delete(obj);__object_delete(pic);__object_delete(pdl);}MSComm控件OnComm对象大事:#include "apdefap.h"void OnComm(char* lpszPictureName, char* lpszObjectName ) {#define GetObject GetObject__object *pdl=NULL;__object *pic=NULL;__object *obj=NULL;char *data="";pdl = __object_create("PDLRuntime");if(pdl){printf("portopen get pdl ok ");}pic=pdl-GetPicture("串口通讯C版");if(pic){printf("portopen get pic ok ");obj=pic-GetObject("COM");if(obj){printf("portopen get obj ok ");}SetTagChar("BufferTemp",obj-Input);printf("BufferTemp:%s ",GetTagChar("BufferTemp"));if(strcmp(GetTagChar("BufferTemp"),"")){SetTagChar("Buffer1",GetTagChar("BufferTemp"));}__object_delete(obj);__object_delete(pic);__object_delete(pdl);}“SEND按钮”鼠标左键按下大事:#include "apdefap.h"void OnLButtonDown(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, UINT nFlags, int x, int y)#define GetObject GetObject__object *pdl=NULL;__object *pic=NULL;__object *obj=NULL;char *data="";pdl = __object_create("PDLRuntime"); if(pdl){printf("portopen get pdl ok ");}pic=pdl-GetPicture("串口通讯C版"); if(pic){printf("portopen get pic ok ");}obj=pic-GetObject("COM");if(obj){printf("portopen get obj ok ");}if(strcmp(GetTagChar("Buffer1"),""))obj-Output=GetTagChar("Buffer1"); }__object_delete(obj);__object_delete(pic);__object_delete(pdl);}MSComm控件.rar。
串口MSComm控件五种不同校验方式对数据收发的影响
串口MSComm控件五种不同校验方式对数据收发的影响串口MSComm控件有五种校验方式,分别是无校验(None),奇校验(Odd),偶校验(Even),1校验(Mark),0校验(Space)。
在RS232/RS485/RS422通讯中,通过串口发送一字节(8BIT)数据时,首先发送起始位(固定为0),然后发送8位数据(先低位后高位),如果校验方式不是无校验(None),则紧接着会发送一位校验位,最后发送停止位。
停止位固定为1。
停止位依据串口属性的设置可为1位,1.5位或2位。
为了说明简洁起见,下面均假设停止位位数为1而数据位位数为8。
在数据发送时,如果校验方式设置为无校验(None),则不发送校验位;否则会发送一位校验位。
具体地,如果校验方式设置为1校验(Mark),校验位固定为1;如果校验方式设置为0校验(Space),校验位固定为0;如果校验位为奇校验(Odd),或者偶校验(Even),那么校验位可能为0也可能为1,依据所发送的数据计算得出。
计算方法:如果是奇校验,那么8位数据和1位校验位的累加和必是奇数;对应的,如果是偶校验,8位数据和1位校验位的累加和必为偶数。
比如,数据37,其二进制编码为00100101,编码中含有5个0和3个1,5*0+3*1=3,如果采用奇校验,那么校验位为0;如果使用偶校验,校验位则为1。
使用MSComm控件发送数据时,校验位无需用户干预,数据发送时自动地由操作系统计算、添加、发出。
串口MSComm控件在接收数据时,如果无校验,则只要检测到串口出现了数据,数据总能收到(试验发现,即使停止位为0也不会被认为是错误帧而遭遇抛弃);而采用了某种校验后,只有校验通码正确的数据才能被正确地收到。
试验中发现,发生校验错的那些数据在后面能校验通过的数据被收到时才被输出,输出值一律为5BH。
为什么是5BH(‘[’)呢?不明白,纳闷中…下面是试验过程中的截图:第一组试验:发送方发送的1个数据桢有10位组成:1位起始位,8位数据位,1位停止位试验(1.1)发方:9600,N,8,1(发出的数据位数为8)收方:9600,N,8,1解读:协议完全匹配,所有数据均能被正确收到。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC++MSComm串口发送与接收上位机本设计用VC编写的一个简单的上位机软件,实现功能为:简单的串口数据发送与接收。
具体步骤如下:
一.建立应用程序工程“串口通信_韩季方01”
1.打开VC++6.0—》建立对话框MFC应用程序:串口通信_韩季方01—》
添加基本控件如图1.0。
图1.0
2.添加MSComm控件:Add To Project—》Components and Controls…打开如图1.1,双击“Registered ActiveX Contronls”项—》出现如图1.2—》选择“Microsoft Communications Control,version 6.0”控件—》点击“Insert”—》提示“…”确认即可—》弹出图1.3—》点击“OK”—》再点击“Close”。
下一步,将对话框资源控件中的电话状控件托到对话框中即可,如图1.4。
图1.1
图1.2
图1.3
图1.4 3.编辑控件及其属性设置:如表1.0
4.添加变量及其类型方法如图1.5
图1.5
二.初始化串口:设置MSComm控件属性
打开Class Wizard—》Member Variables—》选IDC_MSCOMM1—》点击“Add Varialbe…”—》添加变量m_ctrlComm。
如图1.5。
之后,在工作空间打开文件如图2.0—》在函数OnInitDialog中添加代码如图2.1。
图2.0
图2.1
三.添加串口事件消息处理函数OnComm()
打开Class Wizard—》Member Maps—》Class Name中选择C_01Dlg—》在Object Ids中选择IDC_MSCOMM1—》在Message中选中OnComm—》单击“Add Function”按钮—》将函数名改为OnComm(好记而已)—》单击OK,完成后如图3.0
同理在函数OnComm()中添加代码如图3.1
图3.0
图3.1
四.发送数据
为发送按钮添加一个单击信息,即BN_CLICKED处理函数。
打开Class Wizard—》Member Maps—》Class Name中选择C_01Dlg—》选中IDC_BUTTON_MANUALSEND—》选中BN_CLICKED—》单击“Add Function”按钮—》将函数名改为OnButtonManualsend函数—》单击OK,完成后如图4.0 同理在函数OnButtonManualsend()中添加代码如图4.1
图4.0
图4.1
五.完成后,单击编译、连接、运行
如果在编译时出现错误,直接按“Ctrl+F5”即可。
如果没有错误则运行结果为图5.0
图5.0
六.实验结果
通过虚拟串口软件Virtual Serial Ports Driver XP连接好串口COM3和COM4,如图6.0
然后,打开串口调试助手,选择COM4,与运行的串口通信软件进行通信,本实验成功通信,结果如图6.1
图6.1
七.结束语
本实验参考《Visual C++_Turbo C串口通信编程实践》,在此过程中,我感谢好友志强哥的热心帮助。
《完》。