资源描述
,单击此处编辑母版标题样式,*,工控程序设计,工控程序设计,学习情景,2.2,串口设备数据的接收和处理,学习情景,2.2,串口设备数据的接收和处理,2.2.1,学习要点,1.,知识点:,SerialPort,类实例的构造,接收串口数据的方法,接收超时异常处理,,HSDZC,电能综合测试仪的数据格式,数据帧片段的缓存方法,2.,技能点:应用程序项目和,SerialPort,对象的创建,串口数据接收,接收数据的缓存和数据帧的提取,2.2.2,任务描述,某些串口设备能够定时、主动地向上位机发送数据,处于上位机端的工业控制程序,需要获取串口收到的数据并进行分析和处理。利用,.NET Framework 2.0,及更高版本提供的,SerialPort,类可以比较方便地在,C#,应用程序中实现串口通信功能。从编程的角度看,串口数据的接收就是利用,SerialPort,对象的,Read,或,ReadByte,方法将操作系统存放在串口输入缓冲区中的数据读入到一个字节数组中。,该教学情景通过串口数据接收、接收数据的缓存、数据帧的提取、浮点数解码这几个实施步骤,达到使用,SerialPort,对象接收单个串口设备(下位机)数据的目的,。,学习情景,2.2,串口设备数据的接收和处理,2.2.3,相关知识,1,SerialPort,类实例的构造,SerialPort,类是从,.NET Framework 2.0,版本开始提供的一个串口控制类,该类包含在,System.IO.Ports,命名空间中,使用该类的实例可以打开串口,并发送数据。,通过构造函数可以产生,SerialPort,类的实例,,SerialPort,类的构造函数在定义时进行了重载,表,2.2.1,中列出了这些重载构造函数的接口定义:,表,2.2.1,SerialPort,类的构造函数定义,表,2.2.1,SerialPort,类的构造函数定义,构造函数的接口定义,功能说明,public,SerialPort,();,使用默认属性值创建,SerialPort,类的新实例,其中数据位数的默认值为,8,,校验位的默认值为,None,,停止位的默认值为,1,,默认端口名称为,COM1,。,学习情景,2.2,串口设备数据的接收和处理,public,SerialPort(string,portName,);,使用指定的端口名称初始化,SerialPort,类的新实例,其它参数采用默认值,public,SerialPort(string,portName,int,baudRate,);,使用指定的端口名称和波特率初始化,SerialPort,类的新实例,其它参数采用默认值,public,SerialPort(string,portName,int,baudRate,Parity,parity,);,使用指定的端口名称、波特率和奇偶校验位初始化,SerialPort,类的新实例,其它参数采用默认值,public,SerialPort(string,portName,int,baudRate,Parity,parity,int,dataBits,);,使用指定的端口名称、波特率、校验位和数据位初始化,SerialPort,类的新实例,其它参数采用默认值,public,SerialPort(string,portName,int,baudRate,Parity,parity,int,dataBits,StopBits,stopBits,);,使用指定的端口名称、波特率、奇偶校验位、数据位和停止位初始化,SerialPort,类的新实例,学习情景,2.2,串口设备数据的接收和处理,除了在构造,SerialPort,类实例的时候可以对端口名称、波特率、奇偶校验位、数据位和停止位进行设置外,构造好,SerialPort,类实例后,还可以通过,PortName,、,BaudRate,、,Parity,、,DataBits,、,StopBits,属性对这些参数进行修改,因此构造,SerialPort,类实例的程序书写形式比较灵活。,2,串口的打开和关闭,SerialPort,类中与串口打开和关闭相关的成员如下:,(1)Open,方法,Open,方法打开新的串口连接,该方法不带参数,接口定义如下:,public void Open(),(2)Close,方法,Close,方法关闭已经打开的串口连接,该方法不带参数,接口定义如下:,public void Close(),学习情景,2.2,串口设备数据的接收和处理,(3)IsOpen,属性,通过,IsOpen,属性可以获知串口当前是否为打开状态,返回一个,bool,类型的值,该属性只读,接口定义如下:,public,bool,IsOpen,get;,串口不能重复进行打开和关闭操作,在打开或关闭串口前,都要使用该属性检查串口是否已经处于打开或已经处于关闭状态,以免引发异常。,3,接收串口数据的方法,(1)ReadByte,方法,SerialPort,类的,ReadByte,方法可以从串口接收缓冲区中读取一个字节,该方 法的接口定义是:,public,int,ReadByte,();,该方法从串口接收缓冲区中读取一个字节,要和,ReadTimeout,属性配合使用。当调用,ReadByte,方法时,如果接收缓冲区中没有数据,则程序被阻塞,直到缓冲区中有数据或到达,ReadTimeout,属性指定读取数据超时的毫秒数,程序才能继续运行。,学习情景,2.2,串口设备数据的接收和处理,ReadByte,方法返回一个,int,类型的值,在实际应用时,要将返回值强制转换为,byte,类型。,(2)Read,方法,Read,方法从串口接收缓冲区中读取多个字节,该方法的接口定义是:,public,int,Read(byte,buffer,int,offset,int,count);,该方法试图从接收缓冲区中读取,count,个字节,并写入字节数组,buffer,中,写入的起始位置是,offset,,执行后返回实际读取的字节数。例如,现在接收缓冲区中只有,6,个字节,但,count,参数值为,10,,则返回值为,6,。,在实际应用时,通常先通过,SerialPort,对象的,BytesToRead,属性获得接收缓冲区中已有的字节数,并根据该属性值来设置,count,参数。,和,ReadByte,方法不同的是,调用,Read,方法时,不管接收缓冲区中有无数据,都不会对应用程序的当前线程造成阻塞。,学习情景,2.2,串口设备数据的接收和处理,4,接收超时异常处理,当使用,ReadByte,方法从接收缓冲区中读取一个字节时,如果下位机发送过来的数据没有在,ReadTimeout,规定的时间内到达,则会引发,TimeoutException,,应用程序可以捕获该异常,并作相应处理。下面的测试程序说明了超时异常处理的方法:,SerialPort,sp;,private void,btnStart_Click,(object sender,EventArgs,e),byte,firstByte,;,sp.ReadExisting,();/,清空接收缓冲区,准备接收数据,sp.ReadTimeout,=10000;/10,秒内没有收到回复数据,将捕获到异常,try,firstByte,=(,byte)sp.ReadByte,();/,同步读取(程序在此被阻塞),t1.Text=firstByte.ToString(X2);/,显示在文本框,t1,中,catch(,TimeoutException,ex)/,捕获到接收超时异常,t1.Text=,ex.Message,;/,在,t1,中显示异常信息,学习情景,2.2,串口设备数据的接收和处理,图,2.2.1,接收超时异常测试,如上图所示,在点击,“,开始,”,按钮后,程序被阻塞,此时窗口对鼠标和键盘的输入都不响应。为了有足够操作时间,,SerialPort,对象,sp,的,ReadTimeout,属性为,10000,毫秒(,10,秒)。在,10,秒时间内,测试者可以通过串口测试程序发送一个或多个字节过来,此时程序结束阻塞状态继续运行,并在文本框中显示接收到的第,1,个字节;如果,10,秒内没有数据到达,则引发,TimeoutException,。,若上位机程序要一直等待,可以把,ReadTimeout,属性的值设置为,-1,,但在实际应用中一般不这样做。,学习情景,2.2,串口设备数据的接收和处理,5 HSDZC,电能综合测试仪的数据格式,HSDZC,电能综合测试仪在钻机性能测试系统中用于输入功率、输出功率以及功率因素(参见引言介绍)。该设备提供两种电脑测量方式,在仪表提示,“,测量方式,”,时,可以分别按,“,显示,1,”,和,“,显示,2,”,进入。,在测量方式,1,的情况下测试仪每秒通过,RS-232,接口发送,1,组数据,长度,46,字节。信号格式:开始,4,字节均为,FFH,,后续每三个字节构成一个浮点数值,分别表示,I1,、,U1,、,I2,、,U2,、,I3,、,U3,,以及功率因数、视在功率、效率、输入功率、无功功率、负载率、输出功率、转速,共,14,个数据。,在测量方式,2,的情况下测试仪也是每秒通过,RS-232,接口发送,1,组数据,长度,30,字节。信号格式:开始,3,字节均为,12H,、,34H,、,56H,,后续每三个字节构成一个浮点数值,分别表示,I1,、,U1,、,P1,、,I2,、,U2,、,P2,、,I3,、,U3,、,P3,,共,9,个数据。,上位机在和,HSDZC,电能综合测试仪进行通信时,不需要向设备写入数据,而是被动地读取设备发送过来的数据。下面的相关知识将进一步介绍对已接收到数据的存储和处理方法。,学习情景,2.2,串口设备数据的接收和处理,构成浮点数值的,3,个字节含义是:第,1,字节,(B1),为尾数低位,第,2,字节,(B2),为尾数高位,第,3,字节,(B3),为阶码指数。其中阶码指数各位的含义如表,2.2.2,所示:,表,2.2.2,阶码指数字节中各位的含义,D7,D6,D5-D0,数值符号:,0,为正,,1,为负,阶码符号:,0,为正,,1,为负,阶码数值,学习情景,2.2,串口设备数据的接收和处理,尾数,B,的值在,0,到,1,之间,计算公式是:,下面的,HexToFloat,函数描述了将,3,个字节转换为浮点数的算法:,private float,HexToFloat(byte,B1,byte B2,byte B3),float f,B,n;/B:,尾数,n:,阶码指数,B=(B2*256+B1)/65536F;,if(B3&0 x80)!=0)/,如果,D7,为,1,,等价于,if(B3=128),B=-B;,B3=(byte)(B3 /,等价于,B3=(byte)(B3-128),if(B3&0 x40)!=0)/,如果,D6,为,1,B3=(byte)(B3,n=-B3;,else,n=B3;,f=B*(float)Math.Pow(2,n);/B,乘以,2,的,n,次方,return f;,学习情景,2.2,串口设备数据的接收和处理,6,数据帧片段的缓存方法,(1),使用集合类存储接收数据,在通信过程中,数据帧表示由多个字节构成的,具有一定格式,表示完整语意的一组数据。例如,在和,HSDZC,电能综合测试仪进行通信时,如果测试仪工作在测量方式,1,,则一帧数据的长度为,46,个字节(包含起始标志和,14,个数值)。,在系统实际运行中,下位机向上位机发送数据时,可能会将数据帧分为几个片段依次发送,或者在一次接收到的数据中包含了不止一帧数据。上位机必须提供一个字节的集合来对接收到的数据进行缓存(暂存),在确认接收完毕一帧数据后,再进行进一步的分析和处理。,.NET Framework 2.0,以上版本提供了,List,类来实现集合元素管理。,List,类支持泛型,在存取,b
展开阅读全文