收藏 分享(赏)

使用SerialPort类设计串口通讯程序.doc

上传人:yjrm16270 文档编号:7451010 上传时间:2019-05-18 格式:DOC 页数:9 大小:84.50KB
下载 相关 举报
使用SerialPort类设计串口通讯程序.doc_第1页
第1页 / 共9页
使用SerialPort类设计串口通讯程序.doc_第2页
第2页 / 共9页
使用SerialPort类设计串口通讯程序.doc_第3页
第3页 / 共9页
使用SerialPort类设计串口通讯程序.doc_第4页
第4页 / 共9页
使用SerialPort类设计串口通讯程序.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

1、使用 SerialPort 类设计串口通讯程序一 概述 输送带控制模块的核心技术是与 PLC 的串口通讯,在 Visual Studio 6.0 中编写串口通讯程序,一般都使用 Microsoft Communication Control(简称 MSComm)的通讯控件,只要通过对此控件的属性和事件进行相应编程操作,就可以轻松地实现串口通讯。但在 Microsoft.Net 技术广泛应用的今天,Visual Studio.Net 没有将此控件加入控件库,所以人们采用了许多方法在 Visual Studio.Net 来编写串口通讯程序:第一种方法是通过采用 Visual Studio 6.0

2、中原来的 MSComm 控件这是最简单的,最方便的方法,但需要注册;第二种方法是采用微软在.NET 推出了一个串口控件,基于.NET 的 P/Invoke 调用方法实现;第三种方法是自己用 API 写串口通信,虽然难度高,但可以方便实现自己想要的各种功能。 现在微软推出了最新版本的 Visual Studio 2005 开发工具,可以不再采用第三方控件的方法来设计串口通讯程序。NET Framework 2.0 类库包含了 SerialPort 类,方便地实现了所需要串口通讯的多种功能,为了使 MSComm 编程方法快速转换到以 SerialPort 类为核心的串口通讯的设计方法,这里着重讨论

3、了Visual Studio 6.0 的 MSComm 控件和 SerialPort 类设计方法的异同点。二SerialPort 常用属性、方法和事件 1命名空间System.IO.Ports 命名空间包含了控制串口重要的 SerialPort 类,该类提供了同步 I/O 和事件驱动的 I/O、对管脚和中断状态的访问以及对串行驱动程序属性的访问,所以在程序代码起始位置需加入 Using System.IO.Ports。2串口的通讯参数串口通讯最常用的参数就是通讯端口号及通讯格式(波特率、数据位、停止位和校验位) ,在 MSComm中相关的属性是 CommPort 和 Settings。Seri

4、alPort 类与 MSComm 有一些区别: 通讯端口号PortName属性获取或设置通信端口,包括但不限于所有可用的 COM 端口,请注意该属性返回类 型为 String,不是 Mscomm.CommPort 的 short 类型。通常情况下,PortName 正常返回的值为 COM1、 COM2,SerialPort 类最大支持的端口数突破了 CommPort 控件中CommPort 属性不能超过 16 的限止,大大方便了用户串口设备的配置。 通讯格式 SerialPort 类对分别用BaudRate、 Parity 、 DataBits、StopBits 属性设置通讯格式中的波特率、校

5、验位、数据位和停止位,其中Parity和StopBits分别是枚举类型Parity、StopBits, Parity 类型中枚举了 Odd(奇)、Even(偶) 、Mark 、None 、Space ,Parity 枚举了None、One 、OnePointFive、Two。 SerialPort 类提供了七个重载的构造函数,既可以对已经实例化的 SerialPort 对象设置上述相关属性的值,也可以使用指定的端口名称、波特率和奇偶校验位数据位和停止位直接初始化 SerialPort 类的新实例。3串口的打开和关闭 SerialPort 类没有采用 MSComm.PortOpen=True/F

6、alse 设置属性值打开关闭串口,相应的是调用类的Open()和 Close()方法。 4. 数据的发送和读取 SerialPort 类调用重载的 Write 和 WriteLine 方法发送数据,其中 WriteLine 可发送字符串并在字符串末尾加入换行符,读取串口缓冲区的方法有许多,其中除了 ReadExisting(读取 SerialPort 对象的流和输入缓冲区中所有立即可用的字节)和 ReadTo(一直读取到输入缓冲区中的指定 value 的字符串),其余的方法都是同步调用,线程被阻塞直到缓冲区有相应的数据或大于 ReadTimeOut 属性设定的时间值后,引发 ReadExist

7、ing 异常。5. DataReceived 事件 该事件类似于 MSComm 控件中的 OnComm 事件,DataReceived 事件在接收到了ReceivedBytesThreshold设置的字符个数或接收到了文件结束字符并将其放入了输入缓冲区时被触发。其中ReceivedBytesThreshold相当于 MSComm 控件的Rthreshold属性,该事件的用法与 MsComm 控件的OnComm 事件在 CommEvent 为 comEvSend 和 comEvEof 时是一致的。三SerialPort 的使用 对于熟悉 MSComm 控件的程序设计者,SerialPort 类是

8、相当容易上手的。在进行串口通讯时,一般的流程是设置通讯端口号及波特率、数据位、停止位和校验位,再打开端口连接,发送数据,接收数据,最后关闭端口连接这样几个步骤。 SerialPort 类读取数据的许多方法是同步阻塞调用,尽量避免在主线程中调用,可以使用异步处理或线程间处理调用这些读取数据的方法。 由于 DataReceived 事件在辅线程被引发,当收到完整的一条数据,返回主线程处理或在窗体上显示时,请注意跨线程的处理,C#可采用控件异步委托的方法 Control.BeginInvoke 及同步委托的方法 Invoke。1以添加控件的方式(有用户界面) VB:1) 从工具箱选择 SerialP

9、ort 控件添加到窗体上,命名为 SpCom 。2) 设置通讯端口号及波特率、数据位、停止位和校验位。SpCom.PortName = “COM1“SpCom.BaudRate = 9600SpCom.Parity = IO.Ports.Parity.NoneSpCom.DataBits = 8SpCom.StopBits = IO.Ports.StopBits.One3) 发送数据SpCom.Write(TextSendData.Text)4) 添加接受事件Private Sub SpCom_DataReceived(ByVal sender As Object, ByVal e AsSys

10、tem.IO.Ports.SerialDataReceivedEventArgs) Handles SpCom.DataReceived5) 读取数据Dim strT As StringstrT = SpCom.ReadExisting()C:1) 从工具箱选择 SerialPort 控件添加到窗体上,命名为 SpCom 。2) 设置通讯端口号及波特率、数据位、停止位和校验位。SpCom.PortName = “COM1“;SpCom.BaudRate = 9600;SpCom.Parity = IO.Ports.Parity.None;SpCom.DataBits = 8;SpCom.Sto

11、pBits = IO.Ports.StopBits.One;3) 发送数据SpCom.Write(TextSendData.Text) ;4) 添加接受事件private void serialPortCom2_DataReceived(object sender,System.IO.Ports.SerialDataReceivedEventArgs e)5) 读取数据String strT;strT=SpCom.ReadExisting();2以类的方式 VB:1) 定义 SerialPort 类实例Dim SpCom As New System.IO.Ports.SerialPort()2

12、) 设置通讯端口号及波特率、数据位、停止位和校验位。SpCom.PortName = “COM1“SpCom.BaudRate = 9600SpCom.Parity = IO.Ports.Parity.NoneSpCom.DataBits = 8SpCom.StopBits = IO.Ports.StopBits.One或是定义时直接初始化Dim SpCom As New System.IO.Ports.SerialPort(“COM1“, 9600, IO.Ports.Parity.Even, 8, IO.Ports.StopBits.None)3) 发送数据SpCom.Write(Text

13、SendData.Text)4) 添加接受事件a) 在运行时将事件与事件处理程序相关联AddHandler SpCom.DataReceived, AddressOf EventReceiveData说明:AddressOf 创建引用特定过程的过程委托实例AddressOf 运算符可以用作委托构造函数的操作数,或可以用在编译器能够确定委 托类型的上下文中。b) 添加事件处理程序(签名一定要一致)Sub EventReceiveData(ByVal sender As Object, ByVal e AsSystem.IO.Ports.SerialDataReceivedEventArgs)5)

14、 读取数据Dim strT As StringstrT = SpCom.ReadExisting()C:1) 添加引用using System.IO.Ports;2) 定义 SerialPort 类实例private SerialPort SpCom2 = new SpCom (“COM2“, 9600,Parity.None, 8, StopBits.One);3) 设置通讯端口号及波特率、数据位、停止位和校验位。SpCom.PortName = “COM1“;SpCom.BaudRate = 9600;SpCom.Parity = IO.Ports.Parity.None;SpCom.Da

15、taBits = 8;SpCom.StopBits = IO.Ports.StopBits.One;或是定义时直接初始化private SerialPort SpCom2 = new SpCom (“COM2“, 9600,Parity.None, 8, StopBits.One);4) 发送数据SpCom.Write(TextSendData.Text);5) 添加接受事件a) 在运行时将事件与事件处理程序相关联(通过委托实现)SpCom.DataReceived += new SerialDataReceivedEventHandler(SpCom2_DataReceived);说明:Se

16、rialDataReceivedEventHandler 委托 表示将处理 SerialPort 对象的 DataReceived 事件的方法b) 添加事件处理程序(签名一定要一致)private void SpCom_DataReceived(object sender, SerialDataReceivedEventArgs e)6) 读取数据string data = SpCom .ReadExisting();3委托方法的使用 VB:1) 声明委托Delegate Sub myMethodDelegate(ByVal text As String)任何具有匹配参数类型和返回类型的过程均

17、可用来创建此委托类的实例。然后就可以通过委托实例来调用过程。2) 定义一个委托实例Dim myD1 As New myMethodDelegate(AddressOf myShowStringMethod)3) 定义一个实例方法Sub myShowStringMethod(ByVal myString As String)4) 调用myD1(strData)Invoke(myD1, strData)Invoke 提供对某一对象公开的属性和方法的访问。C:1) 声明委托delegate void HandleInterfaceUpdateDelegate(string text);表示委托,委托

18、是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。2) 定义一个委托实例并实例化委托对象HandleInterfaceUpdateDelegate interfaceUpdateHandle;interfaceUpdateHandle = new HandleInterfaceUpdateDelegate(UpdateReceiveTextBox);3) 定义一个实例方法private void UpdateReceiveTextBox(string text)4) 调用Invoke(interfaceUpdateHandle, data);Invoke 提供对某一对象公开的属性和方

19、法的访问。 4ClassLibrary 的使用 VB:1) 建立一个 ClassLibrary 项目。 在“文件”菜单上,选择“新建项目”,在“新建项目”对话框的“模板”窗格中,单击“类库”。类库名为 Persons,类名改为 Player。2) 添加属性。a) 方法一Public Alive As Booleanb) 方法二Private nameValue As StringPublic Property Name() As StringGetName = nameValueEnd GetSet(ByVal value As String)nameValue = valueEnd SetE

20、nd Property3) 添加方法。Public Function FullName() As StringEnd Function4) 添加事件。a) 声明Event AnEvent(ByVal EventNumber As Integer)b) 触发事件RaiseEvent AnEvent(5)5) 类库的使用。a) 声明类库对象。Dim Player1 As New Persons.Playerb) 属性使用。Player1.Alive = truePlayer1.Name = “Andrew“c) 方法使用。Dim strT As StringstrT = player1.FullN

21、amed) 事件使用。AddHandler Player1.AnEvent, AddressOf person1_AnEventPrivate Sub Player1_AnEvent(ByVal p As Integer)MsgBox(Player1.Name d) 方法二private double seconds;public double Hoursget return seconds / 3600; set seconds = value * 3600; 3) 添加方法。public void ShowYear(object sender, EventArgs e)seconds =

22、5;4) 添加事件。a) 定义委托(与 ClassPerson平级)public delegate void SampleEventDelegate(object sender, EventArgs e);b) 声明public event SampleEventDelegate SampleEvent;c) 触发事件SampleEvent(this, e);5) 类库的使用。a) 声明类库对象。private ClassLibraryPersons.ClassPerson clPersons=new ClassLibraryPersons.ClassPerson() ;b) 属性使用。clP

23、ersons.Alive = trueclPersons.Hours = 3;c) 方法使用。clPersons.ShowYear(sender ,e);d) 事件使用。clPersons.SampleEvent += new ClassLibraryPersons.SampleEventDelegate (clPersons_SampleEvent);private void clPersons_SampleEvent(object sender, EventArgs e)5WindowsControlLibrary 的使用 VB:1) 建立一个 WindowsClassLibrary 项目

24、。在“文件”菜单上,选择“新建项目”,在“新建项目”对话框的“模板”窗格中,单击“Windows 控件库”。控件库名为NamesControl,类名改为 NamesUserControl。2) 添加属性。a) 方法一Public Alive As Booleanb) 方法二Private nameValue As StringPublic Property Name() As StringGetName = nameValueEnd GetSet(ByVal value As String)nameValue = valueEnd SetEnd Property3) 添加方法。(Public

25、Function FullName() As StringEnd Function4) 添加事件。a) 声明Event AnEvent(ByVal EventNumber As Integer)b) 触发事件RaiseEvent AnEvent(5)5) 控件的使用。a) 添加控件。工具箱(鼠标右键)选择项.NetFrameWork 组件浏览选择要添加的控件确定在工具箱上选择控件添加到窗体上b) 属性使用。Player1.Alive = truePlayer1.Name = “Andrew“c) 方法使用。Dim strT As StringstrT = player1.FullNamed)

26、事件使用(属性中选择事件直接添加事件)。Private Sub NamesUserControl1_AnEvent(ByVal EventNumber As System.Int32) Handles NamesUserControl1.AnEventEnd SubC#:1) 建立一个 WindowsClassLibrary 项目。在“文件”菜单上,选择“新建项目”,在“新建项目”对话框的“模板”窗格中,单击“Windows 控件库”。控件库名为WindowsControlLibraryPersons,类名改为 UserControl1。2) 添加属性。Public bool Alive; (

27、无效)private double seconds;public double Hoursget return seconds / 3600; set seconds = value * 3600; 3) 添加方法。public void ShowYear(object sender, EventArgs e)seconds = 5;4) 添加事件。a) 定义委托(与 ClassPerson平级)public delegate void SampleEventDelegate(object sender, EventArgs e);b) 声明public event SampleEventDe

28、legate SampleEvent;c) 触发事件SampleEvent(this, e);5) 类库的使用。a) 添加控件。工具箱(鼠标右键)选择项.NetFrameWork 组件浏览选择要添加的控件确定在工具箱上选择控件添加到窗体上b) 属性使用。userControl11.Hours = 8; c) 方法使用。userControl11.ShowYear ();d) 事件使用(属性中选择事件直接添加事件)。private void userControl11_SampleEvent(object sender, EventArgs e)四、 几种方法试验测试1. 中文以及中文特殊字符不

29、能识别2. 在同一台计算机上以 1ms 速度向 Com1 发送字符串(包括英文字母,数字和特殊符号),在 Com2串口接受(Com1 和 Com2 通过 WF19 相连),测试时间为 30 分钟,接受字符串无丢失无乱码。(cpu 1.8 内存 512)3. 采用全局变量实现在当收到完整的一条数据,返回主线程在窗体上显示,发送字符串速度大于100ms 时,测试时间为 30 分钟, 显示接受的字符串没有问题;当发送速度时 50ms,80ms 时,显示接受字符串有丢失现象。(cpu 1.8 内存 512)4. 通过 SerialPort 传输数据时处理 ErrorReceived 事件以检测和响应错误。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报