您的位置:首页 > 其它

自定义串口通信类的实现(SerialPort)

2008-12-15 18:54 429 查看
using System;

using System.Collections.Generic;

using System.Text;

using System.IO.Ports;

using System.Threading;

namespace CommPort

{

enum optype

{

Continues,

Orders

}

/// <summary>

/// 串口操作类

/// </summary>

public class CommOp

{

private SerialPort commport ;

List<byte> list = new List<byte>();

/// <summary>

/// 设置标示位,防止close时存在I/O操作

/// </summary>

bool sign = false;

/// <summary>

/// 自定义串口操作类构造函数

/// </summary>

/// <param name="sp"></param>

public CommOp(SerialPort sp)

{

this.commport = sp;

}

public CommOp()

{

}

/// <summary>

/// 连续方式获得磅秤数据,注意磅秤设备应该标定为"连续方式"

/// </summary>

/// <returns></returns>

public string GetContinueData()

{

string strReceive = "";

if (sign)

{

byte firstbyte = Convert.ToByte(commport.ReadByte());

//判断第一个字节是否是起始位:16进制的0x02

if (firstbyte == 0x02)

{

//定义接收数据长度

int bytesRead = 10;

//数据接收字节数组

byte[] bytesData = new byte[bytesRead];

//接收字节

byte byteData;

for (int i = 0; i <= bytesRead - 1; i++)

{

try

{

if (commport.IsOpen)

{

byteData = Convert.ToByte(commport.ReadByte());

//判断数据结束字节

if (byteData == 0x03)

{

break;

}

bytesData[i] = byteData;

}

}

catch (Exception ex)

{

throw new Exception(ex.Message);

}

}

//将字节数组转换成字符串

strReceive = System.Text.Encoding.Default.GetString(bytesData);

}

}

return GetWeightData(strReceive, optype.Continues);

}

/// <summary>

/// 通过上位机指令方式(由通讯协议获得,如:02 41 42 30 33 03)获取磅秤数据,注意磅秤设备应该标定为"指令方式".

/// </summary>

/// <returns></returns>

public string GetDataByOrder(byte[] byts)

{

string strReceive = "";

if (sign)

{

//发送读取指令

commport.Write(byts, 0, byts.Length);

//等待数据进入缓冲区

Thread.Sleep(500);

//接收缓冲区中数据的字节数

int int_Len = commport.BytesToRead;

//接收数据

byte[] bytes = new byte[int_Len];

commport.Read(bytes, 0, int_Len);

//将数据存入字符串缓冲区中

if (int_Len >= 12)

{

for (int i = 0; i < bytes.Length; i++)

{

list.Add(bytes[i]);

}

strReceive = System.Text.Encoding.Default.GetString(list.ToArray());

list.Clear();

}

}

return GetWeightData(strReceive, optype.Orders);

}

/// <summary>

/// 根据通讯协定分析传输数据(如,有效数据位,小数点位等)

/// </summary>

/// <param name="data"></param>

/// <returns></returns>

private string GetWeightData(string data,optype type)

{

double d = 0;

switch (type)

{

case optype.Orders:

d = Convert.ToDouble(data.Substring(4, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(10, 1)));

break;

case optype.Continues:

d = Convert.ToDouble(data.Substring(1, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(7, 1)));

break;

}

return d.ToString().PadLeft(7,'0');

}

/// <summary>

/// 打开串行接口

/// </summary>

public void Open()

{

try

{

if (!commport.IsOpen)

{

commport.Open();//打开串口方法

Thread.Sleep(1500);

sign = true;

}

}//抛出异常

catch (Exception ex)

{

throw new Exception(ex.Message);

}

}

/// <summary>

/// 关闭串行接口

/// </summary>

public void Close()

{

try

{

if (commport.IsOpen)

{

sign = false;

Thread.Sleep(1500);

commport.DiscardInBuffer();

commport.Close();

}

}

catch (Exception ex)

{

throw new Exception(ex.Message);

}

}

}

}

这里采用了两种方式进去读取:
1.连续方式:只要磅秤显示有数据,数据就会源源不断的抛入缓冲区,电脑则可以在此时进行读取并分析。通常可以采用serialPort的DataReceived事件处理。
优点:实时性好。
缺点:数据过多,分析效果不太好。
2.指令方式:联机电脑发送读取指令给磅秤,磅秤则发送相应的数据信息到缓冲区(没有其他信息),我们可以获取并分析。
优点:数据单一,分析容易
缺点:需要手动更新获取数据(可以结合Timer组件实现实时更新数据的效果)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: