类别:程序开发

日期:2023-01-03 浏览:1961 评论:0

  • 纯小白教程,串口通信,实例自定义类,调用方法即可使用,可自己加定时器实现自动发送。

  • 界面.xaml

<Grid>
     <Button x:Name="BtConnect" Content="建立连接" HorizontalAlignment="Left" Margin="33,24,0,0" VerticalAlignment="Top" Width="75" Height="50" Click="BtConnect_Click"/>
     <Button x:Name="BtBreak" Content="断开连接"  HorizontalAlignment="Left" Margin="33,90,0,0" VerticalAlignment="Top" Width="75" Height="50" Click="BtBreak_Click"/>

     <TextBox x:Name="TxSend" HorizontalAlignment="Left" Height="90" Margin="173,250,0,0"  Text="TextBox" VerticalAlignment="Top" Width="421"/>
     <TextBox x:Name="TxRece" HorizontalAlignment="Left" Margin="173,90,0,0" TextWrapping="Wrap"  Text="TextBlock" VerticalAlignment="Top" Height="129" Width="421" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Visible"/>

     <Button x:Name="BtTxSend" Content="发送消息" HorizontalAlignment="Left" Margin="634,250,0,0" VerticalAlignment="Top" Width="75" Height="90" Click="BtTxSend_Click"/>
     <Button x:Name="BtClearTxRece" Content="清空接收" HorizontalAlignment="Left" Margin="634,129,0,0" VerticalAlignment="Top" Width="75" Height="90" Click="BtClearTxRece_Click"/>
     <StackPanel Orientation="Horizontal">
         <TextBlock Text="  本地连接号:" VerticalAlignment="Bottom" Height="30" HorizontalAlignment="Left" />
         <TextBlock x:Name="T_Data" Text="1" VerticalAlignment="Bottom" Height="30" HorizontalAlignment="Left" />
     </StackPanel>
     <CheckBox x:Name="CB_SendType" Content="HEX发送" Margin="173,224,535.6,170" FlowDirection="RightToLeft"/>
     <CheckBox x:Name="CB_ReceType" Content="HEX接收" Margin="173,63,513.6,330" FlowDirection="RightToLeft"/>
 </Grid>
  • 后端.xmal.cs

public partial class MainWindow : Window
 {
     public MainWindow()
        {
            InitializeComponent();
            SerialPortInit();
        }

     private CsMySerialPort mySerialPort = new CsMySerialPort();
     private CsMySerialPort.SerialPortParm SpParm;

     private void SerialPortInit()
        {
            SpParm.strPortName = "COM1";
            SpParm.strBaudRate = "9600";
            SpParm.strDataBits = "8";
            SpParm.strStopBits = "1";
            SpParm.strParity = "1";
            mySerialPort.ReceEvent += ReceDataClick;
            mySerialPort.SendEvent += IsHEXClick;
        }

     private bool ReceSerialPort(string strIn)
        {
            var strCompare = strIn.Split('-');
            if (strCompare.Count() > 1)
            {
                if (strCompare[0] == "#Sp000")
                {
                    T_Data.Text = SpParm.strPortName + "已连接";
                    return false;
                }
                if (strCompare[0] == "#Sp404")
                {
                    T_Data.Text = SpParm.strPortName + "已断开";
                    return false;
                }
            }
            return true;
        }

     private bool IsHEXClick(string strIn)
        {
            if (strIn == "#HEXSend")
                return (bool)CB_SendType.IsChecked;
            return true;
        }

     private bool ReceDataClick(string strIn)
        {
            if (strIn == "#HEXRece")
                return (bool)CB_ReceType.IsChecked;

            System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate ()
            {
                if (!ReceSerialPort(strIn))
                    return;
                if (false)
                    TxRece.Text += strIn;
                else
                    TxRece.Text += strIn + "\r\n";
            });
            return true;
        }

     private void BtClearTxRece_Click(object sender, RoutedEventArgs e) => TxRece.Text = string.Empty;

     private void BtTxSend_Click(object sender, RoutedEventArgs e) => mySerialPort.ComSend(TxSend.Text);//HEX 输入格式要求 末尾不要输入空格和回车 ASCII 随意

     private void BtConnect_Click(object sender, RoutedEventArgs e) => mySerialPort.OpenSerialPort(SpParm);

     private void BtBreak_Click(object sender, RoutedEventArgs e) => mySerialPort.CloseSerialPort();
 }
  • 基于SerialPort类自定义的串口类

public class CsMySerialPort
{
    /// <summary>
        /// 作者:WangJunLiang || Wechat:Joronwongx
        /// </summary>
    private SerialPort SPserialPort = null;

    //byte字节数组转string
    private string ConverToString(byte[] data)
        {
            StringBuilder stb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                if ((int)data[i] > 15)
                {
                    stb.Append(Convert.ToString(data[i], 16).ToUpper()); //添加字符串
                }
                else  //如果是小于0F需要加个零
                {
                    stb.Append("0" + Convert.ToString(data[i], 16).ToUpper());
                }
                if (i != data.Length - 1)
                    stb.Append(" ");
            }
            return stb.ToString();
        }

    //string转byte字节数组
    private byte[] StringToConver(string str)
        {
            String[] SendArr = str.Split(' ');//以空格分开
            byte[] decBytes = new byte[SendArr.Length];
            for (int i = 0; i < SendArr.Length; i++)
                decBytes[i] = Convert.ToByte(SendArr[i], 16);
            return decBytes;
        }

    //初始化
    public struct SerialPortParm
    {
        public string strPortName;
        public string strBaudRate;
        public string strDataBits;
        public string strStopBits;
        public string strParity;
        public StopBits GetStopBits()
            {
                StopBits stopBits = StopBits.One;
                switch (strStopBits)
                {
                    case "1": stopBits = StopBits.One; break;
                    case "2": stopBits = StopBits.Two; break;
                    case "1.5": stopBits = StopBits.OnePointFive; break;
                    default: break;
                }
                return stopBits;
            }
        public Parity GetParity()
            {
                Parity parity = Parity.None;
                switch (strParity)
                {
                    case "0": parity = Parity.None; break;
                    case "1": parity = Parity.Odd; break;
                    case "2": parity = Parity.Even; break;
                    default: break;
                }
                return parity;
            }
    }

    public delegate bool ReceClientData(string strRece);
    public event ReceClientData ReceEvent;
    public event ReceClientData SendEvent;

    //内容监听
    private void ReceSerialPortDataClick(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                System.Windows.Application.Current.Dispatcher.Invoke((Action)delegate ()
                {
                    if (ReceEvent("#HEXRece"))
                    {
                        int nCnt = SPserialPort.BytesToRead;
                        byte[] Readbuffer = new byte[nCnt];
                        SPserialPort.Read(Readbuffer, 0, nCnt);
                        ReceEvent(ConverToString(Readbuffer));
                    }
                    else
                    {
                        string strReceData = SPserialPort.ReadExisting();
                        ReceEvent(strReceData);
                    }
                });
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                ReceEvent(string.Format("[Error]-{0}", ex.Message));
            }
        }

    //打开实现
    public bool OpenSerialPort(SerialPortParm parm)
        {
            try
            {
                if (SPserialPort != null)
                    return false;
                SPserialPort = new SerialPort
                {
                    PortName = parm.strPortName,
                    BaudRate = int.Parse(parm.strBaudRate),
                    DataBits = int.Parse(parm.strDataBits),
                    StopBits = parm.GetStopBits(),
                    Parity = parm.GetParity(),

                    WriteBufferSize = 1048576,
                    ReadBufferSize = 2097152,
                    Encoding = System.Text.Encoding.GetEncoding("UTF-8"),
                    Handshake = Handshake.None,
                    RtsEnable = true
                };
                SPserialPort.DataReceived += new SerialDataReceivedEventHandler(ReceSerialPortDataClick);//接收响应函数

                SPserialPort.Open();
                ReceEvent(string.Format("#Sp000-{0}", parm.strPortName));
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                return false;
            }
        }

    //关闭实现
    public bool CloseSerialPort()
        {
            try
            {
                if (SPserialPort != null && SPserialPort.IsOpen)
                {
                    SPserialPort.Close();
                    SPserialPort = null;
                    ReceEvent("#Sp404-");
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                return false;
            }
        }

    //发送实现
    public bool ComSend(string strIn)
        {
            try
            {
                if (SPserialPort != null && SPserialPort.IsOpen)
                {
                    if (SendEvent("#HEXSend"))
                    {
                        byte[] decBytes = StringToConver(strIn);
                        SPserialPort.Write(decBytes, 0, decBytes.Length);
                    }
                    else
                        SPserialPort.Write(strIn.ToCharArray(), 0, strIn.Length); /* ASCII字符串发送 */
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                return false;
            }
        }
}


本文标题:C# WPF 基于SerialPort类实现串口通信,打开、关闭、接收、发送,支持HEX数据和ASCII数据收发。
本文链接:https://vtzw.com/post/1073.html
作者授权:除特别说明外,本文由 零一 原创编译并授权 零一的世界 刊载发布。
版权声明:本文不使用任何协议授权,您可以任何形式自由转载或使用。
 您阅读本篇文章共花了: 

 可能感兴趣的文章

评论区

发表评论 / 取消回复

必填

选填

选填

◎欢迎讨论,请在这里发表您的看法及观点。