找回密码
 注册

QQ登录

只需一步,快速开始

搜索

[工业通信] C#语言的串口通信类

[复制链接]
448316256 发表于 2019-3-3 16:25:54 | 显示全部楼层 |阅读模式
厂商
厂商: 其他
C#语言的串口通信类,有问题及时回帖
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO.Ports;
  6. using System.Threading.Tasks;


  7. //串口进行操作的类,其中包括写和读操作,类可设置串口参数、设置接收函数、打开串口资源、关闭串口资源,操作完成后,
  8. //一定要关闭串口、接收串口数据事件、接收数据出错事件、获取当前全部串口、
  9. //把字节型转换成十六进制字符串等功能。这个串口类已经过了调试,可以使用:
  10. namespace 串口接收发送
  11. {
  12. public class SerialClass

  13.     {
  14.         public SerialClass1 sc3 = new SerialClass1();
  15.         SerialPort _serialPort = null;
  16.         public string strRec {get;set; }
  17.         public int RecCount;
  18.         public int replaceCount;
  19.       
  20.         //定义委托

  21.         public delegate void SerialPortDataReceiveEventArgs(object sender, SerialDataReceivedEventArgs e, byte[] bits);

  22.         //定义接收数据事件
  23.         public event SerialPortDataReceiveEventArgs DataReceived;

  24.         //定义接收错误事件
  25.         //public event SerialErrorReceivedEventHandler Error;
  26.         //接收事件是否有效 false表示有效
  27.         public bool ReceiveEventFlag = false;

  28.         #region 获取串口名
  29.         private string protName;
  30.         public string PortName
  31.         {
  32.             get { return _serialPort.PortName; }
  33.             set
  34.             {
  35.                 _serialPort.PortName = value;
  36.                 protName = value;
  37.             }

  38.         }

  39.         #endregion

  40.         #region 获取比特率

  41.         private int baudRate;

  42.         public int BaudRate
  43.         {

  44.             get { return _serialPort.BaudRate; }

  45.             set
  46.             {
  47.                 _serialPort.BaudRate = value;
  48.                 baudRate = value;
  49.             }

  50.         }

  51.         #endregion

  52.         #region 默认构造函数

  53.         /// <summary>
  54.         /// 默认构造函数,操作COM1,速度为9600,没有奇偶校验,8位字节,停止位为1 "COM1", 9600, Parity.None, 8, StopBits.One
  55.         /// </summary>

  56.         public SerialClass()
  57.         {
  58.             _serialPort = new SerialPort();
  59.         }

  60.         #endregion

  61.         #region 构造函数
  62.         /// <summary>
  63.         /// 构造函数,
  64.         /// </summary>
  65.         /// <param name="comPortName"></param>

  66.         public SerialClass(string comPortName)
  67.         {
  68.             _serialPort = new SerialPort(comPortName);
  69.             _serialPort.BaudRate = 9600;
  70.             _serialPort.Parity = Parity.Even;
  71.             _serialPort.DataBits = 8;
  72.             _serialPort.StopBits = StopBits.One;
  73.             _serialPort.Handshake = Handshake.None;
  74.             _serialPort.RtsEnable = true;
  75.             _serialPort.ReadTimeout = 2000;

  76.             setSerialPort();
  77.         }

  78.         #endregion

  79.         #region 构造函数,可以自定义串口的初始化参数

  80.         /// <summary>
  81.         /// 构造函数,可以自定义串口的初始化参数
  82.         /// </summary>
  83.         /// <param name="comPortName">需要操作的COM口名称</param>
  84.         /// <param name="baudRate">COM的速度</param>
  85.         /// <param name="parity">奇偶校验位</param>
  86.         /// <param name="dataBits">数据长度</param>
  87.         /// <param name="stopBits">停止位</param>

  88.         public SerialClass(string comPortName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
  89.         {
  90.             _serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
  91.             _serialPort.RtsEnable = true;  //自动请求
  92.             _serialPort.ReadTimeout = 3000;//超时
  93.             setSerialPort();

  94.         }

  95.         #endregion

  96.         #region 析构函数
  97.         /// <summary>
  98.         /// 析构函数,关闭串口
  99.         /// </summary>
  100.         ~SerialClass()
  101.        {
  102.            if (_serialPort.IsOpen)
  103.                _serialPort.Close();
  104.        }

  105.         #endregion

  106.         #region 设置串口参数
  107.         /// <summary>
  108.         /// 设置串口参数
  109.         /// </summary>
  110.         /// <param name="comPortName">需要操作的COM口名称</param>
  111.         /// <param name="baudRate">COM的速度</param>
  112.         /// <param name="dataBits">数据长度</param>
  113.         /// <param name="stopBits">停止位</param>
  114.         public void setSerialPort(string comPortName, int baudRate, int dataBits, int stopBits )
  115.         {
  116.             if (_serialPort.IsOpen)
  117.             {
  118.                 _serialPort.Close();
  119.             }               
  120.             _serialPort.PortName = comPortName;
  121.             _serialPort.BaudRate = baudRate;
  122.             _serialPort.Parity = Parity.None;
  123.             _serialPort.DataBits = dataBits;
  124.             _serialPort.StopBits = (StopBits)stopBits;
  125.             _serialPort.Handshake = Handshake.None;
  126.             _serialPort.RtsEnable = false;
  127.             _serialPort.ReadTimeout = 3000;
  128.             _serialPort.ReadBufferSize = 31 * 1024;
  129.             _serialPort.NewLine = "/r/n";
  130.             setSerialPort();

  131.         }

  132.         #endregion

  133.         #region 设置接收函数

  134.         /// <summary>
  135.         /// 设置串口资源,还需重载多个设置串口的函数
  136.         /// </summary>

  137.         void setSerialPort()
  138.         {

  139.             if (_serialPort != null)
  140.             {
  141.                 //设置触发DataReceived事件的字节数为1
  142.                 _serialPort.ReceivedBytesThreshold = 1;
  143.                 //接收到一个字节时,也会触发DataReceived事件
  144.                 _serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);
  145.                 //接收数据出错,触发事件
  146.                 _serialPort.ErrorReceived += new SerialErrorReceivedEventHandler(_serialPort_ErrorReceived);

  147.                 //打开串口
  148.                 //openPort();

  149.             }

  150.         }

  151.         #endregion

  152.         #region 打开串口资源
  153.         /// <summary>
  154.         /// 打开串口资源
  155.         /// <returns>返回bool类型</returns>
  156.         /// </summary>
  157.         public bool openPort()
  158.         {
  159.             bool ok = false;
  160.             //如果串口是打开的,先关闭
  161.             if (_serialPort.IsOpen)
  162.                 _serialPort.Close();

  163.             try
  164.             {
  165.                 //打开串口
  166.                 _serialPort.Open();
  167.                 ok = true;

  168.             }
  169.             catch (Exception Ex)
  170.             {
  171.                 throw Ex;
  172.             }
  173.             return ok;

  174.         }

  175.         #endregion

  176.         #region 关闭串口

  177.         /// <summary>
  178.         /// 关闭串口资源,操作完成后,一定要关闭串口
  179.         /// </summary>
  180.         public void closePort()
  181.         {
  182.             //如果串口处于打开状态,则关闭
  183.             if (_serialPort.IsOpen)
  184.             {
  185.                 _serialPort.Close();
  186.             }            
  187.         }

  188.         #endregion

  189.         #region 接收串口数据事件
  190.         /// <summary>
  191.         /// 接收串口数据事件
  192.         /// </summary>
  193.         /// <param name="sender"></param>
  194.         /// <param name="e"></param>
  195.         void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
  196.         {
  197.             //禁止接收事件时直接退出
  198.             if (ReceiveEventFlag)
  199.             {
  200.                 return;
  201.             }

  202.             try
  203.             {

  204.                 //System.Threading.Thread.Sleep(5);

  205.                 byte[] _data = new byte[_serialPort.BytesToRead];

  206.                 _serialPort.Read(_data, 0, _data.Length);
  207.                 string strRecBuffer  =   Encoding.Default.GetString(_data);
  208.                 RecCount = RecCount + 1;
  209.                 if (RecCount == 1)
  210.                 {
  211.                     replaceCount = 0;
  212.                 }
  213.                 if (strRecBuffer.Contains("^PON^") && replaceCount == 0)
  214.                 {
  215.                     replaceCount = replaceCount + 1;
  216.                     strRecBuffer = strRecBuffer.Replace("^PON^", "^RON^");
  217.                 }

  218.                 sc3.SendData(strRecBuffer);
  219.                 strRec = strRec + strRecBuffer;
  220.                
  221.                 if (_data.Length == 0) { return; }

  222.                 if (DataReceived != null)
  223.                 {   
  224.                     DataReceived(sender, e, _data);
  225.                 }

  226.                 //_serialPort.DiscardInBuffer();  //清空接收缓冲区  

  227.             }

  228.             catch (Exception ex)
  229.             {

  230.                 throw ex;

  231.             }

  232.         }

  233.         #endregion

  234.         #region 接收数据出错事件
  235.         /// <summary>
  236.         /// 接收数据出错事件
  237.         /// </summary>
  238.         /// <param name="sender"></param>
  239.         /// <param name="e"></param>
  240.         void _serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
  241.         {

  242.         }

  243.         #endregion

  244.         #region 发送数据string类型

  245.         public void SendData(string data)
  246.         {

  247.             //发送数据
  248.             //禁止接收事件时直接退出

  249.             if (ReceiveEventFlag)
  250.             {
  251.                 return;
  252.             }

  253.             if (_serialPort.IsOpen)
  254.             {
  255.                 _serialPort.Write(data);

  256.             }

  257.         }

  258.         #endregion

  259.         #region 发送数据byte类型

  260.         /// <summary>
  261.         /// 数据发送
  262.         /// </summary>
  263.         /// <param name="data">要发送的数据字节</param>
  264.         public void SendData(byte[] data, int offset, int count)
  265.         {

  266.             //禁止接收事件时直接退出

  267.             if (ReceiveEventFlag)
  268.             {
  269.                 return;
  270.             }

  271.             try
  272.             {

  273.                 if (_serialPort.IsOpen)
  274.                 {
  275.                     //_serialPort.DiscardInBuffer();//清空接收缓冲区

  276.                     _serialPort.Write(data, offset, count);

  277.                 }

  278.             }

  279.             catch (Exception ex)
  280.             {
  281.                 throw ex;
  282.             }

  283.         }

  284.         #endregion

  285.         #region 发送命令

  286.         /// <summary>

  287.         /// 发送命令
  288.         /// </summary>
  289.         /// <param name="SendData">发送数据</param>
  290.         /// <param name="ReceiveData">接收数据</param>
  291.         /// <param name="Overtime">超时时间</param>
  292.         /// <returns></returns>

  293.         public int SendCommand(byte[] SendData, ref  byte[] ReceiveData, int Overtime)
  294.         {
  295.             if (_serialPort.IsOpen)
  296.             {

  297.                 try
  298.                 {

  299.                     ReceiveEventFlag = true;        //关闭接收事件

  300.                     _serialPort.DiscardInBuffer();  //清空接收缓冲区               

  301.                     _serialPort.Write(SendData, 0, SendData.Length);

  302.                     int num = 0, ret = 0;

  303.                     System.Threading.Thread.Sleep(10);

  304.                     ReceiveEventFlag = false;      //打开事件

  305.                     while (num++ < Overtime)
  306.                     {

  307.                         if (_serialPort.BytesToRead >= ReceiveData.Length)

  308.                             break;

  309.                         System.Threading.Thread.Sleep(10);

  310.                     }

  311.                     if (_serialPort.BytesToRead >= ReceiveData.Length)
  312.                     {
  313.                         ret = _serialPort.Read(ReceiveData, 0, ReceiveData.Length);
  314.                     }

  315.                     else
  316.                     {
  317.                         ret = _serialPort.Read(ReceiveData, 0, _serialPort.BytesToRead);
  318.                     }

  319.                     ReceiveEventFlag = false;      //打开事件

  320.                     return ret;

  321.                 }
  322.                 catch (Exception ex)

  323.                 {

  324.                     ReceiveEventFlag = false;

  325.                     throw ex;

  326.                 }

  327.             }

  328.             return -1;

  329.         }

  330.         #endregion

  331.         #region 获取串口
  332.         /// <summary>
  333.         /// 获取所有已连接短信猫设备的串口
  334.         /// </summary>
  335.         /// <returns></returns>

  336.         public string[] serialsIsConnected()
  337.         {
  338.             List<string> lists = new List<string>();

  339.             string[] seriallist = getSerials();

  340.             foreach (string s in seriallist)
  341.             {

  342.             }
  343.             return lists.ToArray();

  344.         }

  345.         #endregion

  346.         #region 获取当前全部串口资源

  347.         /// <summary>

  348.         /// 获得当前电脑上的所有串口资源

  349.         /// </summary>

  350.         /// <returns></returns>

  351.         public string[] getSerials()

  352.         {

  353.             return SerialPort.GetPortNames();

  354.         }

  355.         #endregion



  356.         #region 字节型转换16

  357.         /// <summary>

  358.         /// 把字节型转换成十六进制字符串

  359.         /// </summary>

  360.         /// <param name="InBytes"></param>

  361.         /// <returns></returns>

  362.         public static string ByteToString(byte[] InBytes)

  363.         {

  364.             string StringOut = "";

  365.             foreach (byte InByte in InBytes)

  366.             {

  367.                 StringOut = StringOut + String.Format("{0:X2} ", InByte);

  368.             }

  369.             return StringOut;

  370.         }

  371.         #endregion

  372.         #region 十六进制字符串转字节型

  373.         /// <summary>

  374.         /// 把十六进制字符串转换成字节型(方法1)

  375.         /// </summary>

  376.         /// <param name="InString"></param>

  377.         /// <returns></returns>

  378.         public static byte[] StringToByte(string InString)

  379.         {

  380.             string[] ByteStrings;

  381.             ByteStrings = InString.Split(" ".ToCharArray());

  382.             byte[] ByteOut;

  383.             ByteOut = new byte[ByteStrings.Length];

  384.             for (int i = 0; i <= ByteStrings.Length-1 ; i++)

  385.             {

  386.                 //ByteOut[i] = System.Text.Encoding.ASCII.GetBytes(ByteStrings[i]);

  387.                 ByteOut[i] = Byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);

  388.                 //ByteOut[i] =Convert.ToByte("0x" + ByteStrings[i]);

  389.             }

  390.             return ByteOut;

  391.         }

  392.         #endregion

  393.         #region 十六进制字符串转字节型

  394.         /// <summary>

  395.         /// 字符串转16进制字节数组(方法2)

  396.         /// </summary>

  397.         /// <param name="hexString"></param>

  398.         /// <returns></returns>

  399.         public static byte[] strToToHexByte(string hexString)

  400.         {

  401.             hexString = hexString.Replace(" ", "");

  402.             if ((hexString.Length % 2) != 0)

  403.                 hexString += " ";

  404.             byte[] returnBytes = new byte[hexString.Length / 2];

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

  406.                 returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);

  407.             return returnBytes;

  408.         }

  409.         #endregion

  410.         #region 字节型转十六进制字符串

  411.         /// <summary>

  412.         /// 字节数组转16进制字符串

  413.         /// </summary>

  414.         /// <param name="bytes"></param>

  415.         /// <returns></returns>

  416.         public static string byteToHexStr(byte[] bytes)

  417.         {

  418.             string returnStr = "";

  419.             if (bytes != null)

  420.             {

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

  422.                 {

  423.                     returnStr += bytes[i].ToString("X2");

  424.                 }

  425.             }

  426.             return returnStr;

  427.         }

  428.         #endregion

  429.     }

  430. }



  431. using System;
  432. using System.Collections.Generic;
  433. using System.ComponentModel;
  434. using System.Data;
  435. using System.Drawing;
  436. using System.Linq;
  437. using System.Text;
  438. using System.Threading.Tasks;
  439. using System.Windows.Forms;
  440. using System.IO.Ports;
  441. using System.IO;
  442. using System.Threading;

  443. namespace 串口发送
  444. {
  445.     public partial class Form1 : Form
  446.     {

  447.         SerialClass sc1 = new SerialClass();
  448.         public Form1()
  449.         {
  450.             InitializeComponent();
  451.             
  452.         }



  453.         private void btn_OpenSerialPort_Click(object sender, EventArgs e)
  454.         {
  455.            
  456.             sc1.setSerialPort("COM1", 115200, 8, 1);
  457.             sc1.openPort();
  458.         }

  459.         private void btn_CloseSerialPort_Click(object sender, EventArgs e)
  460.         {
  461.             sc1.closePort();
  462.         }

  463.         private void btn_ReadFile_Click(object sender, EventArgs e)
  464.         {
  465.             string path = "E:\\SF.txt";
  466.             StreamReader sr = new StreamReader(path, Encoding.Default);
  467.             string line;
  468.             while ((line = sr.ReadLine()) != null)
  469.             {
  470.                 textBox1.Text = textBox1.Text + line;
  471.             }

  472.         }

  473.         private void btn_Clear_Click(object sender, EventArgs e)
  474.         {
  475.             textBox1.Text = "";
  476.         }

  477.         private void btn_SendMessage_Click(object sender, EventArgs e)
  478.         {
  479.             //Thread sendThread = new Thread(SendData);
  480.             //sendThread.IsBackground = true;
  481.             //sendThread.Start();
  482.             sc1.SendData(textBox1.Text);
  483.         }

  484.         public void SendData()
  485.         {
  486.             string path = "E:\\SF.txt";
  487.             StreamReader sr = new StreamReader(path, Encoding.Default);
  488.             string line = "";
  489.             while ((line = sr.ReadLine()) != null)
  490.             {
  491.                 //textBox1.Text = textBox1.Text + line;
  492.                 sc1.SendData(line);
  493.                 Thread.Sleep(5);
  494.             }

  495.         }

  496.     }
  497. }
复制代码

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-11-23 11:58

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表