串口通讯常用类

1.Mymath

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BIZHexagonalDevice
{
    class MyMath
    {
        /// <summary>
        /// 字符串转BYTE数组
        /// </summary>
        /// <param name="data"></param>
        /// <returns>高位在前</returns>
        static public byte[] StrToByte(string data)
        {
            byte[] bt = new byte[data.Length / 2];
            for (int i = 0; i < data.Length / 2; i++)
            {
                bt[i] = Convert.ToByte(data.Substring(i * 2, 2), 16);
            }
            return bt;
        }
        /// <summary>
        ///  byte数组转STRING
        /// </summary>
        /// <param name="Bytes"></param>
        /// <returns></returns>
        static public string BytetoStr(byte[] Bytes)
        {
            string str = string.Empty;
            str = BitConverter.ToString(Bytes, 0).Replace("-", string.Empty).ToLower();
            return str;

        }

        /// <summary>
        /// 计算CRC-16
        /// </summary>
        /// <param name="data"></param>
        /// <returns>高位在前</returns>
        static public string CRC_16(string data)
        {
            if ((data.Length % 2) != 0) { throw new Exception("Parameter\"data\"length error"); }
            byte[] tmp = StrToByte(data);

            /*
            1、预置16位寄存器为十六进制FFFF(即全为1)。称此寄存器为CRC寄存器; 
            2、把第一个8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器; 
            3、把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位; 
            4、如果最低位为0:重复第3步(再次移位); 如果最低位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或; 
            5、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理; 
            6、重复步骤2到步骤5,进行下一个8位数据的处理; 
            7、最后得到的CRC寄存器即为CRC码。
            */
            UInt16 CRCREG = (UInt16)0xffff;
            for (int i = 0; i < tmp.Length; i++)
            {
                CRCREG = (UInt16)(CRCREG ^ (UInt16)tmp[i]);//<< 8;
                for (int j = 0; j < 8; j++)
                {
                    UInt16 CRCtmp = (UInt16)(CRCREG & (UInt16)0x0001);
                    CRCREG = (UInt16)(CRCREG >> (UInt16)1);
                    if (CRCtmp == (UInt16)1)
                    {
                        CRCREG = (UInt16)(CRCREG ^ (UInt16)0xA001);
                    }
                }
            }

            string strtmp = CRCREG.ToString("X4");

            return strtmp.Substring(2, 2) + strtmp.Substring(0, 2);
            //return strtmp;
        }
       
    }
}

2.modbus rtu通讯协议

using System;
using System.Collections.Generic;
using System.Text;
//using WFDLL;

namespace WfpRTU
{
    public class Modbus
    {
        protected string _PortName;

        public string PortName
        {
            get { return _PortName; }
            set
            {
                _PortName = value;
                SP.PortName = _PortName;
            }
        }
        protected int _PortBaud;

        public int PortBaud
        {
            get { return _PortBaud; }
            set
            {
                _PortBaud = value;
                SP.PortBaud = _PortBaud;
            }
        }
        protected int _Timeout;

        public int Timeout
        {
            get { return _Timeout; }
            set
            {
                _Timeout = value;
                SP.Timeout = _Timeout;
            }
        }

        protected System.IO.Ports.Parity _parity;

        public System.IO.Ports.Parity Parity
        {
            get { return _parity; }
            set 
            {
                _parity = value;
                SP.Parity = _parity;
            }
        }

        protected MySerialPort SP = new MySerialPort();

        public Modbus()
        {
        }

        public Modbus(string PName, int PBaud, System.IO.Ports.Parity parity, int timeout)
        {
            _PortName = PName;
            _PortBaud = PBaud;
            _Timeout = timeout;
            _parity = parity;
            SP.PortName = _PortName;
            SP.PortBaud = _PortBaud;
            SP.Timeout = timeout;
            SP.Parity = parity;
        }

        /// <summary>
        /// 读取设备识别码(F0x2B)
        /// </summary>
        /// <param name="CommAddr">通讯地址</param>
        /// <param name="ReadDevId">ReadDevId</param>
        /// <param name="ObjectId">对象ID</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public MODBUSRESULT ReadDeviceRegister(string CommAddr, UInt16 ReadDevId, UInt16 ObjectId, out string data)
        {
            if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append("2B");            //功能码
            cmd.Append("0E");            //MEI类型
            cmd.Append(ReadDevId.ToString("X2"));       //01
            cmd.Append(ObjectId.ToString("X2"));        //00
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(),7, out data);
        }
        /// <summary>
        /// 读取多个线圈
        /// </summary>
        /// <param name="CommAddr">通讯地址</param>
        /// <param name="FunCode">功能码</param>
        /// <param name="StartAddr">起始地址</param>
        /// <param name="RegCount">线圈数</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public MODBUSRESULT ReadMultiCoil(string CommAddr, byte FunCode, UInt16 StartAddr, UInt16 RegCount, out string data)
        {
            if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            cmd.Append(RegCount.ToString("X4"));        //线圈数
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            double cnt=RegCount / 8;
            return SP.SendAndReceive(cmd.ToString(), Convert.ToUInt16(Math.Ceiling(cnt)) + 4 + CommAddr.Length / 2, out data);
        }

        /// <summary>
        /// 写多个线圈
        /// </summary>
        /// <param name="CommAddr"></param>
        /// <param name="StartAddr"></param>
        /// <param name="RegCount"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public MODBUSRESULT WriteMultiCoil(string CommAddr, byte FunCode, UInt16 StartAddr, string data)
        {
            if ((data.Length % 2) != 0) { throw new Exception("Data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            //int RegCount = data.Length / 4;
            int bytecnt = data.Length / 2;
            int RegCount = bytecnt * 8;//--------------------------------------tgw-------------------
            cmd.Append(RegCount.ToString("X4"));        //寄存器数
            //int bytecnt = RegCount * 2;
            cmd.Append(bytecnt.ToString("X2"));        //字节计数
            cmd.Append(data);
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(), 7 + CommAddr.Length / 2, out data);
        }

        / <summary>
        / 读取输入寄存器(F0x04)
        / </summary>
        / <param name="CommAddr">通讯地址</param>
        / <param name="StartAddr">起始地址</param>
        / <param name="RegNum">寄存器数</param>
        / <param name="data">数据</param>
        / <returns></returns>
        //public MODBUSRESULT ReadInputRegister(string CommAddr, UInt16 StartAddr, UInt16 RegCount, out string data)
        //{
        //    if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr数据长度错误"); }
            
        //    StringBuilder cmd = new StringBuilder();
        //    cmd.Append(CommAddr);        //通讯地址
        //    cmd.Append("04");
        //    cmd.Append(StartAddr.ToString("X4"));       //起始地址
        //    cmd.Append(RegCount.ToString("X4"));        //寄存器数
        //    cmd.Append(MyMath.CRC_16(cmd.ToString()));
        //    return SP.SendAndReceive(cmd.ToString(), RegCount * 2 + 4 + CommAddr.Length / 2, out data);
        //}

        / <summary>
        / 读取保持寄存器(F0x03)
        / </summary>
        / <param name="CommAddr">通讯地址</param>
        / <param name="StartAddr">起始地址</param>
        / <param name="RegNum">寄存器数</param>
        / <param name="data">数据</param>
        / <returns></returns>
        //public MODBUSRESULT ReadHoldingRegister(string CommAddr, UInt16 StartAddr, UInt16 RegCount, out string data)
        //{
        //    if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr数据长度错误"); }
            
        //    StringBuilder cmd = new StringBuilder();
        //    cmd.Append(CommAddr);        //通讯地址
        //    cmd.Append("03");
        //    cmd.Append(StartAddr.ToString("X4"));       //起始地址
        //    cmd.Append(RegCount.ToString("X4"));        //寄存器数
        //    cmd.Append(MyMath.CRC_16(cmd.ToString()));
        //    return SP.SendAndReceive(cmd.ToString(), RegCount * 2 + 4 + CommAddr.Length / 2, out data);
        //}

        /// <summary>
        /// 读取多个寄存器
        /// </summary>
        /// <param name="CommAddr">通讯地址</param>
        /// <param name="FunCode">功能码</param>
        /// <param name="StartAddr">起始地址</param>
        /// <param name="RegCount">寄存器数</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public MODBUSRESULT ReadMultiRegister(string CommAddr, byte FunCode,UInt16 StartAddr, UInt16 RegCount, out string data)
        {
            if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr data length error"); }
            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            string str = RegCount.ToString("X4");
            cmd.Append(str);        //寄存器数
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(), RegCount * 2 + 4 + CommAddr.Length / 2, out data);
        }

        /// <summary>
        /// 写多个寄存器
        /// </summary>
        /// <param name="CommAddr"></param>
        /// <param name="StartAddr"></param>
        /// <param name="RegCount"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public MODBUSRESULT WriteMultiRegister(string CommAddr, byte FunCode, UInt16 StartAddr, string data)
        {
            if ((data.Length % 4) != 0) { throw new Exception("Data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            int RegCount = data.Length / 4;
            cmd.Append(RegCount.ToString("X4"));        //寄存器数
            int bytecnt = RegCount * 2;
            cmd.Append(bytecnt.ToString("X2"));        //字节计数
            cmd.Append(data);
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(), 7 + CommAddr.Length / 2, out data);
        }


        public static string GetResultMsg(MODBUSRESULT ret)
        {
            string msg = "";
            switch (ret)
            {
                case MODBUSRESULT.DataAddrInvalid:
                    msg = "Data address invalid";
                    break;
                case MODBUSRESULT.DataCheckFall:
                    msg = "Data validation failure";
                    break;
                case MODBUSRESULT.DataFormatError:
                    msg = "Data format error";
                    break;
                case MODBUSRESULT.DataValueInvalid:
                    msg = "Data value invalid";
                    break;
                case MODBUSRESULT.OK:
                    msg = "Correct";
                    break;
                case MODBUSRESULT.PortOpenFall:
                    msg = "Open port failure";
                    break;
                case MODBUSRESULT.Timeout:
                    msg = "Communication timeout";
                    break;
                case MODBUSRESULT.UnknownError:
                    msg = "Unknown error";
                    break;
                case MODBUSRESULT.UnknownFunCode:
                    msg = "Unsupported function code";
                    break;
                default:
                    msg = "Unknown error";
                    break;
            }
            return msg;
        }

        public static string GetRegValue(string data,int StartReg,int RegNum)//按字符
        {
            int offset = 6;
            int startpoint = offset + StartReg * 4;
            int len = RegNum * 4;
            return data.Substring(startpoint, len).ToUpper();
        }

        public static string GetByteValue(string data, int StartReg, int RegNum)//按字符
        {
            int offset = 6;
            int startpoint = offset + StartReg * 2;
            int len = RegNum * 2;
            return data.Substring(startpoint, len).ToUpper();
        }
    }
}

3.csv文件读写

/*
 * Created by SharpDevelop.
 * User: sz
 * Date: 2007/12/10
 * Time: 18:09
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace WfpRTU
{
	/// <summary>
	/// CSVUtil is a helper class handling csv files.
	/// </summary>
	public class CSVUtil
	{
		private CSVUtil()
		{
		}
		//write a new file, existed file will be overwritten
		public static void WriteCSV(string filePathName,List<String[]>ls)
		{
			WriteCSV(filePathName,false,ls);
		}
		//write a file, existed file will be overwritten if append = false
		public static void WriteCSV(string filePathName,bool append, List<String[]> ls)
		{
			StreamWriter fileWriter=new StreamWriter(filePathName,append,Encoding.Default);
			foreach(String[] strArr in ls)
			{
				fileWriter.WriteLine(String.Join(",",strArr));
			}
			fileWriter.Flush();
			fileWriter.Close();
			
		}
		public static List<String[]> ReadCSV(string filePathName)
		{
			List<String[]> ls = new List<String[]>();
			StreamReader fileReader=new   StreamReader(filePathName);  
			string strLine="";
			while (strLine != null)
			{
				strLine = fileReader.ReadLine();
				if (strLine != null && strLine.Length>0)
				{
					ls.Add(strLine.Split(','));
					//Debug.WriteLine(strLine);
				}
			} 
			fileReader.Close();
			return ls;
		}
		
	}
}

  4.串口接收触发事件

 private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(1000);
            if (Com.IsOpen)
            {
                try
                {
                    byte[] ReDatas = new byte[Com.BytesToRead];
                    if (Com.BytesToRead <= 0)
                    {
                        txtData.Text = "没查询到数据,请检查设置";

                    }

                    else
                    {
                        Com.Read(ReDatas, 0, ReDatas.Length);
                        string temHex = BytesToHex(ReDatas);
                    
                    }
                catch (Exception ex)
                {

                    MessageBox.Show(ex.Message, "出错提示!!!!!");
                    txtData.Text = "";
                }

            }
            else
            {
                txtData.Clear();
                txtData.Text = "请检查串口是否打开";
            }
        }

  

 

转载于:https://www.cnblogs.com/-CarryRao/p/10819304.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Java中,可以使用JavaComm API来实现串口通讯。以下是实现串口通讯的基本步骤: 1. 下载并安装JavaComm API,该API包括了访问串口的和方法。 2. 导入JavaComm API库。 ```java import javax.comm.*; ``` 3. 使用CommPortIdentifier获取可用的串口。 ```java Enumeration portList = CommPortIdentifier.getPortIdentifiers(); while (portList.hasMoreElements()) { CommPortIdentifier portId = (CommPortIdentifier) portList.nextElement(); if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { System.out.println(portId.getName()); } } ``` 4. 打开选定的串口。 ```java CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM1"); SerialPort serialPort = (SerialPort) portId.open("MyApp", 2000); ``` 5. 配置串口参数,例如波特率、数据位、停止位、奇偶校验位等。 ```java serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); ``` 6. 获取输入输出流并进行数据传输。 ```java InputStream in = serialPort.getInputStream(); OutputStream out = serialPort.getOutputStream(); out.write("Hello World".getBytes()); byte[] buffer = new byte[1024]; int len = in.read(buffer); System.out.println(new String(buffer, 0, len)); ``` 7. 关闭串口。 ```java serialPort.close(); ``` 以上是Java实现串口通讯的基本步骤,根据具体需求可以进行进一步的修改和扩展。 ### 回答2: Java可以通过使用第三方库来实现串口通讯。其中最常用的库之一是RXTX,它可以在 Java 平台上提供串口通讯的功能。 RXTX是一个开源的串口通讯库,支持跨平台运行。以下是实现串口通讯的一般步骤: 1. 添加RXTX库:首先,你需要下载RXTX库的最新版本。然后,将库的JAR文件添加到你的Java项目的classpath中。 2. 打开串口:使用RXTX提供的,打开你要进行通讯的串口。你可以选择串口的名称、波特率和其他参数。 3. 设置串口监听器:通过注册一个监听器来监听串口的输入数据。这样,当串口接收到数据时,你就可以在监听器中处理它。 4. 发送数据:使用串口对象的输出流,你可以将数据发送到串口设备上。 5. 接收数据:使用串口对象的输入流,你可以读取从串口设备接收到的数据。 6. 关闭串口:当你完成通讯后,要记得关闭串口,释放资源。 需要注意的是,在使用RXTX库之前,你需要在你的操作系统上安装相应的驱动程序。具体的驱动程序安装方法和操作系统有关。 总结起来,通过使用RXTX库,我们可以在Java平台上实现串口通讯。我们可以打开和关闭串口,发送和接收数据。这为与硬件设备的交互提供了便利,例如与传感器、机器人或其他串口设备进行通讯。 ### 回答3: 串口通讯在Java中可以通过Java的Comm API来实现。下面是一个简单的示例来说明如何使用Java实现串口通讯。 1. 首先,我们需要下载并安装Java Comm API。可以从Oracle官方网站上下载相应版本的Java Comm API。 2. 在Java代码中,我们需要导入相应的,包括javax.comm包中的SerialPort和CommPortIdentifier。 3. 然后,我们需要通过调用CommPortIdentifier的getPortIdentifiers()方法获取当前系统中可用的串口列表。 4. 对于每个可用的串口,我们可以调用CommPortIdentifier的方法来获得串口对象。 5. 通过打开串口,我们可以得到一个串口输入流和一个串口输出流。 6. 通过串口输出流,我们可以发送数据。通过串口输入流,我们可以接收数据。 7. 当需要关闭串口时,我们需要调用close()方法来关闭串口。 下面是一个简单的示例代码: ``` import javax.comm.*; public class SerialCommunication { public static void main(String[] args) { CommPortIdentifier portId; try { // 获取当前系统中可用的串口列表 Enumeration portList = CommPortIdentifier.getPortIdentifiers(); while (portList.hasMoreElements()) { // 获取串口对象 portId = (CommPortIdentifier) portList.nextElement(); // 判断串口型 if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { // 打开串口 SerialPort serialPort = (SerialPort) portId.open("SerialCommunication", 2000); // 配置串口参数 serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); // 获取串口输入流和输出流 InputStream in = serialPort.getInputStream(); OutputStream out = serialPort.getOutputStream(); // 使用串口输出流发送数据 out.write("Hello, Serial Port!".getBytes()); out.flush(); // 接收串口输入流数据 byte[] buffer = new byte[1024]; int len = in.read(buffer); String receivedData = new String(buffer, 0, len); System.out.println("Received Data: " + receivedData); // 关闭串口 serialPort.close(); } } } catch (Exception e) { e.printStackTrace(); } } } ``` 这就是一种基本的方法来实现Java中的串口通讯。当然,还有其他的一些高级应用,比如监听串口数据事件等。 希望这个简单的示例可以帮助您理解在Java中如何实现串口通讯

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值