课件:多个串口设备数据的连续采集.ppt_第1页
课件:多个串口设备数据的连续采集.ppt_第2页
课件:多个串口设备数据的连续采集.ppt_第3页
课件:多个串口设备数据的连续采集.ppt_第4页
课件:多个串口设备数据的连续采集.ppt_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

工控程序设计,学习情景2.4 多个串口设备数据的连续采集,学习情景2.4 多个串口设备数据的连续采集,2.4.1 学习要点 1.知识点: 煤矿钻机性能检测设备的数据通信协议,数据帧的校验方法 2.技能点: 校验码的计算,上位机主动模式串口通信类的设计,HC-100智能测控仪、JW-2A扭矩仪、LU-902M位式调节仪数据采集 2.4.2 任务描述 在前一个情景中实现了对单个HSDZC电能综合测试数据的接收。在钻机性能测试系统中,还需要使用JW-2A扭矩仪、HC-100智能测控仪、LU-902M位式调节仪来采集其它参数的值,而这些设备的数据通信规则不同,所以必须对每种设备编写通信程序,并同步、连续地采集多个设备的数据。 该教学情景中先针对上位机主动通信模式设计基类CActiveCOMHelper,再分别对三种不同的仪器分别设计派生类来进行数据管理,实现对多个不同设备进行同步、连续的数据采集。,2.4.3 相关知识 1 煤矿钻机性能检测设备的数据通信协议 (1) HC-100智能测控仪 HC-100智能测控仪可以使用RS232、RS485接口与计算机通讯,数据格式为1个起始位,8个数据位,无奇偶校验,1个停止位,共11位。设备的所有数字变换成ASCII码进行传输:例如:仪表编号Addr=01,测量值=123.4,则数据千位为31H、百位为32H、十位为33H、小数点为2EH,个位为34H,符号位2BH为正,2DH为负。 从仪表读数据的指令格式为:EOT+仪表地址编号+52H+参数+ENQ 表2.4.1 发送给HC100的数据格式,仪表返回数据的格式为:STX+仪表地址编号+符号位+测量值+校验码+ETX。其中的数据参数值为符号位+4位有效位+小数点,共6位,校验码为前面发送的9个字节之和。 表2.4.2 HC100返回的数据格式,HC-100智能控制仪的数据处理流程如图2.4.1所示,图2.4.1 HC-100智能控制仪数据处理流程,(2)JW-2A扭矩仪 JW-2A扭矩仪采用多机通讯方式,本机地址为0AH。数据位8位,停止位1位。波特率可用跳线选择4800bps或2400bps。奇偶位在这里做地址和数据判别位,1为地址,0为数据。仪器只被地址触发,即上位机只有向仪器发0AH,并且奇偶位为1时,才能得到仪器的响应。仪器被本机地址触发后,向上位机传回本机地址,然后等待上位机发来的命令。受到命令后,根据命令执行不同的任务。命令为一个字节。目前有效的命令有15个,下面叙述各命令代表的任务。 0:读扭矩转速 仪器受到命令后向上位机依次传送扭矩,转速,采样时间3个参数。扭矩、转速为浮点数,每个参数4个字节。采样时间为整数,2个字节。每个参数的传送顺序都是从内存的低地址到高地址 1:存储操作。在测量状态收到此命令,将启动存储操作;在存储状态收到此命令,将退出存储状态。 2:读仪器存储的数据数组。在非存储状态收到此命令,将向上位机传送春初数据的数组。 3:释放操作。在测量状态收到此命令,将启动释放操作;在释放状态仪器不再接受命令。,4:扣除/不扣除转换。在扣除状态收到此命令,将退出扣除状态;在非扣除状态收到此命令,将进入扣除状态。 5:内/外转速显示转换。在显示内转速时收到此命令,将显示外转速;在显示外转速时收到此命令,将显示内转速。 6:调零操作。仪器才测量状态收到此命令,将启动调零操作。 7:读仪器状态。仪器收到命令后向上位机 传送仪器状态字节。状态字节各位的定义如表2.4.3所示。 表2.4.3 JW-2A通信协议,8:读模拟通道数据。仪器收到命令后向上位机依次传送0至7通道的A/D采样结果。每通道2字节,高位在前。低14位表示数值大小,最高2位表示小数点位置。小数点位置为0,有0位小数点;小数点位置为1,有1位小数点;小数点位置为2,有2位小数点。 9:读0点。仪器收到命令后向上位机依次传送10个零点值和其相应的转速值。每个零点6个字节(前4个字节是零点,浮点数,后2个字节是转速,无符号整数,高位在前),共60个字节。 10:写零点。仪器受到命令后准备接受10个零点,共60个字节的数据。上位机应按上述读零点的顺序依次将60个字节写回去。注意,写零点不能少于60字节。 11:读扭矩参数。仪器收到命令后向上位机依次传送11个参数,共24个字节。这11个参数的排列顺序,数据类型,数据长度如表2.4.4所示。 12:写扭矩参数。仪器收到命令后准备接受11个参数,共24个字节的数据。上位机应按上述读扭矩参数的顺序依次将24个字节写回去。注意:写扭矩参数不能少于24字节。 13:读模拟通道量程。仪器收到命令后向上位机依次传送8个通道的量程值。每个量程2个字节,共16个字节。数据类型是无符号整数,高位在前。低14位表示数值大小,最高2位表示小数点位置。小数点位置为0,有0位小数点;小数点位置为1,有1位小数点,小数点位置为2,有2位小数点。,表2.4.4 JW-2A的扭矩参数,14:写模拟通道量程。仪器收到命令后准备接收8个通道的量程表。每个量程2个字节,共16个字节。数据类型是无符号整数,高位在前。低14位表示数值大小,最高2位表示小数点位置。小数点位置为0,有0位小数点;小数点位置为1,有1位小数点,小数点位置为2,有2位小数点。上位机应按上述读模拟通道量程的顺序依次将16个字节写回去。需要注意的是:写模拟通道量程不能少于16字节。,JW-2A扭矩仪的数据采用IEEE浮点数形式表示,需要作浮点数字节数组到浮点数的转换。如果用DCBA表示浮点数,D为高位,A为低位,每个字母表示一个字节,那么DCBA依次为 SXXX XXXX XMMM MMMM MMMM MMMM MMMM MMMM,其中S代表符号,1位,1表示负,0表示正,X代表指数,8位,0到255转换为-127到128,M代表尾数,23位,注意尾数总共24位,最高位等于1是隐含的。 JW-2A扭矩仪的数据处理流程如图2.4.2所示。,图2.4.2 JW2A数据处理流程,另外,仪器处于释放状态时,每释放一组数据都会将数据从串口发送出来。数据格式和发送的顺序同于用0命令读扭矩转速。 (3)LU-902M位式调节仪 LU-902M采用串行异步通讯,提供RS232C、422A或者485通讯接口,波特率有1200、2400、4800、9600四种选择。每帧数据包含1个起始位(第0位),8个数据位(第1-8位),1个“寻址/数据”选择位(第9位,决定指令类别),1个停止位,共11位,数据采用16进制表达。在每个通讯指令中,仪表最后返回信息4FH、4BH表示通讯成功,返回3FH,3FH表示通讯失败。 1)寻址指令 当上位机要对某LU-902M仪表进行通讯操作时,应先对其发寻址指令。寻址指令为单字节指令,第1-8位为地址,第9位(校验位)为“1”(非寻址指令为“0”)。 2)数据读取指令 指令格式:45H 仪表返回:PV、SV、MV、4FH、4BH 其中PV为测量值、SV为设定值、MV为输出值,各占两个字节,低字节在前高字节在后。 3)读参数指令 指令格式:52H + 参数代码 仪表返回:参数值 + 4FH、4BH 4)写参数指令 指令格式:57H + 参数代码 + 参数值 仪表返回:4FH、4BH 5)结束指令 指令格式:4FH或第9位为“1”的非本机寻址指令 仪表无返回,2 数据帧的校验 数据帧校验的目的是为了检查接收到的数据帧的完整性和准确性。和校验位不同,校验位的作用是保证一个数据单位的正确性,是从微观角度考虑。形象地说,校验位保证一个字正确,数据帧校验是保证一段话正确。 对数据帧进行校验的方法是:发送方根据要发送的数据帧,利用某种算法计算出若干字节的校验码,并把校验码附加在数据帧中发送给接收端,接收端接收到数据后,分离出校验码和数据本身,再根据发送方的算法,计算出校验码,如果和接收到的校验码一致,则认为接收到的数据准确无误。串口通信中常用的校验方式有累加和校验、异或和校验、循环冗余校验等。 (1)累加和校验 累加和校验的过程是,发送端将数据的每个字节累加求和,然后截取最低字节(或最低两字节)作为校验码发送给接收端,接收端收到数据后,用同样的方法计算累加和,并与发送过来的校验码进行比较,从而检验发送的数据是否有误。 (2)异或和校验 异或和校验的过程是,发送端取出发送数据的第1个字节,与后续每个字节依次按位异或,然后将计算结果(1个字节)作为校验码发送给接收端,接收端收到数据后,用同样的方法计算异或和,并与发送过来的校验码进行比较,从而检验发送的数据是否有误。,(3)循环冗余校验 循环冗余校验(Cyclical Redundancy Check)简称CRC,它利用除法及余数的原理来作错误侦测。实际应用时,发送端计算出校验码值并附加在数据帧中发送给接收端,接收端对收到的数据重新计算校验码并与收到的校验码相比较,若两个值不同,则说明数据通讯出现错误,要求发送端重新发送。 常用的CRC标准有CRC-12、CRC-16、CRC-CCITT和CRC-32,其中CRC-16和CRC-CCITT用来作一个字节数据的校验,在串口数据校验中最常用的是CRC-16。下面是循环冗余校验码的计算过程: 1)设置CRC寄存器,并给其赋值FFFF(hex)。 2)将数据的第一个字节与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。 3)CRC寄存器向右移一位,MSB(最高有效位)补零,移出并检查LSB(最低有效位)。 4)如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。 5)重复第3与第4步直到8次移位全部完成。此时一个字节数据处理完毕。 6)重复第2至第5步直到所有数据全部处理完成。 7)最终CRC寄存器的内容即为CRC值。 常用的循环冗余校验标准多项式为: CRC-16:X16+ X15+X2+1 CRC-CCITT:X16+X12 +X5+1 CRC-32:X32+X26+X23+X16+X12+X11+X10+ X8+X7+X5+X4+X2+X+1 其中CRC-16多项式对应多项式码为1000 0000 0000 0101(0x8005),CRC-CCITT对应的多项式码为0001 0000 0010 0001(0x1021)。,2.4.4 任务实施 1 校验码的计算 在串口通信通,校验码在保证数据帧的正确性方面具有重要作用,虽然在钻机性能测试系统中只用到累加和校验,但为了能应对串口通信中可能出现的复杂情况,下面对三种校验码的计算都进行具体实现。 (1)累加和校验码的计算 累加和校验码可以取累加和的低8位(1个字节)或低16位(两个字节),在下位机处理能力允许的情况下采用两个字节作校验码可以提高校验的准确度。 下面的C#代码将累加和校验码生成功能封装到CCheck类的方法中,其中CheckSum_1方法计算单字节累加和校验码,CheckSum_2方法计算双字节累加和校验码 class CCheck /函数功能: /计算字节数组b中从offset位置开始的count个元素的单字节累加和校验码 /参数: /b:要计算累加和的字节数组 /offset:要计算累加和的元素的起始位置 /count:要计算累加和的连续元素个数 /返回值:累加和的低8位(单个字节),public static byte CheckSum_1(byte b, int offset, int count) uint sum = 0; for (int i = offset; i offset + count; i+) sum += bi; /数组元素累加求和 return (byte)(sum /函数功能: /计算字节数组b中从offset位置开始的count个元素的双字节累加和校验码 /参数: /b:要计算累加和的字节数组 /offset:要计算累加和的元素的起始位置 /count:要计算累加和的连续元素个数 /返回值:长度为2的字节数组,第1个元素为累加和的低8位 /第2个元素为累加和的高8位,public static byte CheckSum_2(byte b, int offset, int count) uint sum = 0; byte tmp = new byte2; /存放累加和的低8位和高8位 for (int i = offset; i 8); /高8位在后 return tmp; 下面的测试程序调用CheckSum_1方法,计算出长度为1个字节的累加和校验码,并附加在字节数组末尾: byte b =0x41,0x42,0x43,0; /保留一个字节位置存储校验码 byte sum = CCheck.CheckSum_1(b, 0, b.Length - 1); /计算单字节累加和 bb.Length-1 = sum; /附加在字节数组末尾,下面的测试程序调用CheckSum_2方法,计算出长度为两个字节的累加和校验码,并附加在字节数组末尾: byte b =0x41,0x42,0x43,0,0; /保留两个字节位置存储校验码 byte sum = CCheck.CheckSum_2(b, 0, b.Length - 2); /计算双字节累加和 bb.Length-2 = sum0; /附加在字节数组末尾 bb.Length-1 = sum1; (2)异或和校验码的计算 下面的C#代码将异或和校验码生成功能封装到CCheck类的方法中,方法名为XorSum: class CCheck /函数功能: /计算字节数组b中从offset位置开始的count个元素的单字节异或和校验码 /参数: /b:要计算累加和的字节数组 /offset:要参与计算校验码的元素的起始位置 /count:要参与计算校验码的连续元素个数 /返回值:异或和(8位,1个字节),public static byte XorSum(byte b, int offset, int count) byte sum = 0; for (int i = offset; i offset + count; i+) sum = bi; /依次和每个元素进行按位异或运算 return sum; 下面的测试程序调用XorSum方法,计算出长度为1个字节的异或和校验码,并附加在字节数组末尾: byte b =0x41,0x42,0x43,0; /保留一个字节位置存储校验码 byte xorsum = CCheck. XorSum(b, 0, b.Length - 1); /计算异或和 bb.Length-1 = xorsum; /附加在字节数组末尾,(3)循环冗余校验码的计算 下面的C#代码将CRC-16校验码生成功能封装到CCheck类的方法中,方法名为CRC16: class CCheck /函数功能: /计算字节数组b中从offset位置开始的count个元素的循环冗余校验码 /参数: /b:要计算累加和的字节数组 /offset:要参与计算校验码的元素的起始位置 /count:要参与计算校验码的连续元素个数 / CrcPoly:CRC多项式对应的16位二进制编码 /返回值:长度为2的字节数组,第1个元素为校验码的低8位 /第2个元素为校验码的高8位,public static byte CRC16(byte b, int offset, int count, ushort CrcPoly) ushort CrcReg = 0xFFFF; /16位CRC寄存器 uint LSB; /最低有效位 byte tmp = new byte2; for (int i = offset; i = 1; /CRC寄存器逻辑右移1位 if (LSB = 1) CrcReg = CrcPoly; ,tmp0 = (byte)(CrcReg ,2 上位机主动模式串口通信类的设计 煤矿钻机性能测试系统中用到的HC-100智能测控仪、JW-2A扭矩仪和LU-902M位式调节仪与HSDZC电能综合测试仪不同,这些设备需要上位机主动发送命令,才给予回复,因此可以把这三种设备的通信模式归为“上位机主动模式”。 下面将设计上位机主动模式的串口通信类CActiveCOMHelper,和CPassiveCOMHelper类不同的是,CActiveCOMHelper类中增加了一个名为command的成员,存放当前应该执行的命令,线程函数根据该成员的相关属性,就知道现在应该给下位机发送什么命令。由于采用“提问回答”的方式,能够准确控制下位机发送来的数据,故不再需要队列来暂存接收的数据。 CCommand类实现代码如下: public class CCommand public string commandName;/命令名字 public byte cmdContent;/命令的内容 public Parity parity = Parity.None;/发送命令时采用的校验方式 public byte replyContent;/回复内容,public int replyLength;/回复内容的规定长度 public bool isCompleted; /命令是否完成 public CCommand() /创建对象时commandName不能为null,以免后面比较时出错 mandName = “; command成员(CCommand的实例)是UI模块和CActiveCOMHelper对象的连接纽带。UI模块首先查询前一个命令是否完成(isCompleted是否为true),若已经完成,就设置下一条命令的名字、内容、校验方式、回复内容的规定长度,交给CActiveCOMHelper对象去执行;CActiveCOMHelper对象执行完命令后,把回复内容填好,并将完成标志isCompleted设置为true。如此循环,就可以不断让CActiveCOMHelper对象执行命令。这样分工的好处是,处于上层的UI模块没有必要知道如何和串口通信、如何创建线程等等复杂琐碎的具体操作,而只要知道该发什么命令,以及如何处理收到的结果。,CActiveCOMHelper类实现代码如下: public class CActiveCOMHelper public int readTimeOut;/接收数据超时毫秒数 public string portName;/设备所占用的串口名 private bool stopFlag;/线程循环停止标志 private int baudRate, dataBits; private StopBits stopBits; private CCommand command; public delegate void DataReceivedHandler(CActiveCOMHelper sender); public event DataReceivedHandler DataReceived; public CActiveCOMHelper(string portName, int baudRate, int dataBits, StopBits stopBits), this.portName = portName; this.baudRate = baudRate; this.dataBits = dataBits; this.stopBits = stopBits; this.readTimeOut = 3000;/默认3000毫秒读取超时 mand = new CCommand(); /始终保持有一个命令 mand.isCompleted = true; /该命令开始时处于完成状态 public void start() Thread t = new Thread(new ThreadStart(threadFun); t.IsBackground = true; stopFlag = false; t.Start(); ,public void stop() stopFlag = true; public CCommand getCommand() /获取一个克隆的命令对象 CCommand cmd = new CCommand(); Monitor.Enter(this); /线程同步:在进行get操作时,不准进行set操作 mandName = mandName; cmd.cmdContent = command.cmdContent; cmd.parity = command.parity; cmd.replyContent = command.replyContent; cmd.replyLength = command.replyLength; cmd.isCompleted = command.isCompleted; Monitor.Exit(this); return cmd; ,public void setCommand(CCommand cmd) Monitor.Enter(this); /线程同步:在进行set操作时,不准进行get操作 mand = cmd; Monitor.Exit(this); protected virtual bool checkReply(string cmdType, byte bRecv) return false; private void threadFun() SerialPort sp = new SerialPort(portName, baudRate, Parity.None, dataBits, stopBits); try if (sp.IsOpen) sp.Close(); sp.Open(); ,catch return; byte first; byte bRecv, bSend; while (!stopFlag) CCommand cmd = getCommand(); if (cmd.isCompleted = false) try sp.ReadTimeout = readTimeOut; sp.ReadExisting(); /清除接收缓冲区 bSend = cmd.cmdContent;/要发送的内容 sp.Parity = cmd.parity;/校验位 sp.Write(bSend, 0, bSend.Length); first = (byte)sp.ReadByte(); /阻塞方式读取数据,bRecv = new bytecmd.replyLength;/存储回复数据(字节数已经规定) bRecv0 = first; int n = 0;/检查的次数 while (n 3) continue; /等待3次后数据还未到达 sp.Read(bRecv, 1, cmd.replyLength - 1); if (checkReply(mandName, bRecv) cmd.replyContent = bRecv;/填写回复内容 cmd.isCompleted = true;/修改命令完成标志 setCommand(cmd); if (DataReceived != null) /引发事件,通知使用该类的程序 DataReceived(this); ,catch else Thread.Sleep(20);/没有新命令下达,延时防止CPU占用率过高 if (sp != null 在前一个步骤中已经实现了串口数据接收、解析和显示的功能,并且在工作者线程中接收和处理数据,在此期间前台的UI线程能响应用户输入。从功能上看,已经能够满足用户需求,但是从代码的组织和管理角度看,该程序还有比较大问题:负责接收和处理数据的代码和负责显示的代码混杂在一起,不能重复使用,若增加一个同类设备,很多代码还要重写,而且给查看和调试程序也带来较大困难。下面用面向对象方法对程序进行重新设计。,3 HC-100智能测控仪数据采集 HC-100智能测控仪采用以上位机为主导的“提问应答”通信模式,管理该设备的类可以从CActiveCOMHelper类派生而来,命名为CHC100,在类中覆盖checkReply方法,并实现浮点数的解码方法AsciiToFloat。该类的实现代码如下: public class CHC100 : CActiveCOMHelper public CHC100(string portName, int baudRate, int dataBits, StopBits stopBits) : base(portName, baudRate, dataBits, stopBits) /根据命令名称构建命令对象 public CCommand makeCommand(string commandName) CCommand command = new CCommand();,switch (commandName) case “R“: /读数据指令 mandName = commandName; command.replyLength = 11; command.cmdContent = new byte 0x04, 0x30, 0x31, 0x52, 0x30, 0x30, 0x05 ; break; return command; protected override bool checkReply(string cmdType, byte bRecv) switch (cmdType) case “R“: /读数据指令 if (bRecv0 = 0x02 ,return false; public float AsciiToFloat(byte b) StringBuilder s = new StringBuilder(); for (int i = 3; i = 8; i+) /下标为3到8的数据段表示浮点数值 s.Append(char)bi); /将字符连接为字符串 float f = 0F; try f = Single.Parse(s.ToString(); /字符串转换为浮点数 catch return f; ,下面的代码说明了CHC100类在UI模块中的应用。后台工作者线程获得下位机应答数据后,存储在CCommand对象中,不用事件通知UI线程。UI线程每隔1秒钟检查一次命令执行情况,如果命令执行完毕,则读取本次的应答数据,并设置下一次的命令。 private CHC100 hc100; private void btnStart_Click(object sender, EventArgs e) /开始采集数据 hc100 = new CHC100(“COM1“, 9600, 8, StopBits.One); hc100.start(); timer1.Enabled = true; private void btnStop_Click(object sender, EventArgs e) /结束采集 timer1.Enabled = false; hc100.stop(); ,private void timer1_Tick(object sender, EventArgs e) CCommand cmd = hc100.getCommand(); /获取当前命令 if (cmd.isCompleted) /当面命令已完成 CCommand nextCmd = hc100.makeCommand(“R“); /构建下一个命令 hc100.setCommand(nextCmd); if (cmd.cmdContent != null) Trace.WriteLine(“HC100回复:压力:“ + AsciiToFloat(cmd.replyContent); else Trace.WriteLine(mandName + “命令还未完成“); ,4 JW-2A扭矩仪数据采集 JW-2A扭矩仪用于测量钻机的扭矩和转速,该设备和HC-100智能测控仪相似,也采用以上位机为主导的“提问应答”通信模式,不同的是通信方式比HC-100智能测控仪稍微复杂,每次通信需要发送两道命令,首先发寻址指令激活,再发送读数据指令获取数据。 管理该设备的类从CActiveCOMHelper类派生而来,命名为CJW2A,代码如下: class CJW2A : CActiveCOMHelper public CJW2A(string portName, int baudRate, int dataBits, StopBits stopBits) : base(portName, baudRate, dataBits, stopBits) public CCommand makeCommand(string commandName) /根据命令名称构建命令对象 CCommand command = new CCommand();,switch (commandName) case “A“: /寻址指令(激活设备) mandName = commandName; command.replyLength = 1; command.parity = Parity.Mark; command.cmdContent = new byte 0x0A ; break; case “R“: /读数据指令 mandName = commandName; command.replyLength = 10; command.parity = Parity.Space; command.cmdContent = new byte 0x00 ; break; return command; ,protected override bool checkReply(string cmdType, byte bRecv) switch (cmdType) case “A“: /寻址指令 if (bRecv0 = 0x0A) return true; break; case “R“: /读数据指令 if (bRecv0 = 0x02 ,public float HexToFloat(byte data) /4字节转换为浮点数(按照IEEE754规范) int s; /符号位,+1或者-1。 int e; /指数,根据IEEE754,指数部份算出来后要减127 float m; /小数位。 float mreturn; /返回的浮点数,应为:(1+小数位)* 2(指数)*(符号位) s = data0 ,在UI模块中,每个CJW2A对象负则和一个JW-2A扭矩仪通信,由于每次通信过程要发送两道命令,所以代码中采用事件通知方式来使两道命令连贯地发送,当收到第一道命令的回复后,引发事件,在事件处理程序中紧接着发第二道命令。代码如下: private CJW2A jw2a; private void btnStart_Click(object sender, EventArgs e) jw2a = new CJW2A(“COM3“, 4800, 8, StopBits.One); jw2a.DataReceived += new CActiveCOMHelper.DataReceivedHandler(DataReceived); jw2a.start(); timer1.Enabled = true; private void btnStop_Click(object sender, EventArgs e) timer1.Enabled = false; jw2a.stop(); ,private void DataReceived(CActiveCOMHelper sender) CCommand cmd, nextCmd; switch (sender.portName.ToUpper() case “COM3“: /JW2A要先发“A”命令,完成后紧接着发“R”命令 cmd = jw2a.getCommand(); if (mandName = “A“ /处理JW2A的返回结果,cmd = jw2a.getCommand(); if (mandName = “R“ ,5 LU-902M位式调节仪数据采集 LU-902M位式调节仪在钻机性能测试系统中应用最广泛,用于测量大气温度、马达温度、泵温度、油温、冷却水流量、马达进油流量、马达回油流量、马达油压、操纵台噪音、马达噪音等诸多参数,该设备同样采用以上位机为主导的“提问应答”通信模式,它仍然需要激活,不过只激活一次,以后就象HC-100智能测控仪一样发送查询指令获取数据。 管理该设备的类从CActiveCOMHelper类派生而来,命名为CLU902M,代码如下: class CLU902M : CActiveCOMHelper public bool isActive; /设备激活标志 public byte address; /设备地址 public CLU902M(string portName, int baudRate, int dataBits, StopBits stopBits) : base(portName, baudRate, dataBits, stopBits) /根据命令名称构建命令对象,public CCommand makeCommand(string commandName) CCommand command = new CCommand(); switch (commandName) case “A“: /寻址指令(激活设备) mandName = commandName; command.replyLength = 2; command.parity = Parity.Mark; command.cmdContent = new byte address ; break; case “R“: /读数据指令 mandName = commandName; command.replyLength = 8; command.parity = Parity.Space; command.cmdContent = new byte 0x45 ; break; return command; ,protected override bool checkReply(string cmdType, byte bRecv) switch (cmdType) case “A“: /寻址命令 if (bRecv0 = 0x4F ,public float HexToFloat(byte H, byte L) return (float)(H * 256 + L) / 10.0F; 在UI模块中,每个CLU902M对象负则和一个LU-902M位式调节仪通信,程序先判断设备是否激活,未激活前先发寻址命令激活设备,对已经激活的设备,UI线程每隔1秒钟发送读数命令获取参数值。代码如下: private CLU902M lu902m; private void btnStart_Click(object sender, EventArgs e) lu902m = new CLU902M(“COM5“, 9600, 8, StopBits.One); lu902m.address = 0x00;/设

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论