WPF内实现与串口发送数据和接收数据

Posted lonelyxmas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF内实现与串口发送数据和接收数据相关的知识,希望对你有一定的参考价值。

原文:WPF内实现与串口发送数据和接收数据

与串口发送数据和接收数据,在此作一个简单的Demo.此Demo可以实现按下硬件按钮,灯亮,发送灯状态数据过来。并且可以实现几个灯同时亮,发送灯的状态数据过来。PC端实现点击按钮让硬件灯亮。
此处为4个灯,发送过来的数据:0代表暗,1代表亮。列如:1010代表1号灯和3号灯亮,2号和4号灯暗。
发送过去的数据:0代表1号灯亮,1代表1号灯灭、2代表2号灯亮,3代表2号灯灭、4代表3号灯亮,5代表3号灯灭、6代表4号灯亮,7代表4号灯灭。
布局代码:

<Grid>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="112,59,0,0" TextWrapping="Wrap" Name="txtSend" VerticalAlignment="Top" Width="120"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="112,113,0,0" TextWrapping="Wrap" Name="txtReceive" VerticalAlignment="Top" Width="120"/>
        <Button Content="发送" Name="btnSend" HorizontalAlignment="Left" Margin="83,271,0,0" VerticalAlignment="Top" Width="35" Click="btnSend_Click"/>
        <Button Content="发送" Name="btnSend1" HorizontalAlignment="Left" Margin="143,271,0,0" VerticalAlignment="Top" Width="35" Click="btnSend1_Click"/>
        <Button Content="发送" Name="btnSend2" HorizontalAlignment="Left" Margin="203,271,0,0" VerticalAlignment="Top" Width="35" Click="btnSend2_Click"/>
        <Button Content="发送" Name="btnSend3" HorizontalAlignment="Left" Margin="263,271,0,0" VerticalAlignment="Top" Width="35" Click="btnSend3_Click"/>


        <Label Name="one" Background="Red" HorizontalAlignment="Left" Margin="84,190,0,0" VerticalAlignment="Top" Height="24" Width="28"/>
        <Label Name="two" Background="Red" HorizontalAlignment="Left" Margin="144,190,0,0" VerticalAlignment="Top" Height="24" Width="28"/>
        <Label Name="three" Background="Red" HorizontalAlignment="Left" Margin="204,190,0,0" VerticalAlignment="Top" Height="24" Width="28"/>
        <Label Name="four" Background="Red" HorizontalAlignment="Left" Margin="264,190,0,0" VerticalAlignment="Top" Height="24" Width="28"/>



    </Grid>

后台代码:

private SerialPort Sp = new SerialPort();
        public delegate void HandleInterfaceUpdataDelegate(string text);
        private HandleInterfaceUpdataDelegate interfaceUpdataHandle;

        String[] arr = { "0", "0", "0", "0" };//用于存储硬件上面灯状态

其次在Loaded事件添加用于更改串口参数:

 //更改参数
            Sp.PortName = "COM3";
            Sp.BaudRate = 115200;
            Sp.Parity = Parity.None;
            Sp.StopBits = StopBits.One;
编写监听和发送数据事件:
private void Serial()
        {
            Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
            if (!Sp.IsOpen)
            {
                Sp.Open();
            }
            //用字节的形式发送数据
            SendBytesData(Sp);
        }

        //发送二进制数据
        private void SendBytesData(SerialPort Sp)
        {

            byte[] bytesSend = System.Text.Encoding.Default.GetBytes(txtSend.Text);
            Sp.Write(bytesSend, 0, bytesSend.Length);

        }



        public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
           /* byte[] readBuffer = new byte[Sp.ReadBufferSize];
            Sp.Read(readBuffer, 0, readBuffer.Length);
            //Dispatcher.Invoke(interfaceUpdataHandle, new string[]{ Encoding.UTF8.GetString(readBuffer)});
            Dispatcher.Invoke(interfaceUpdataHandle, new string[] { Encoding.ASCII.GetString(readBuffer) });
            //Dispatcher.Invoke(interfaceUpdateHandle, new string[] { Encoding.ASCII.GetString(buf) });*/

            SerialPort serialPort = (SerialPort)(sender);
            System.Threading.Thread.Sleep(100);//延缓一会,用于防止硬件发送速率跟不上缓存数据导致的缓存数据杂乱
            int n = serialPort.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致  
            byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据  
            //received_count += n;//增加接收计数  
            serialPort.Read(buf, 0, n);//读取缓冲数据  
            //因为要访问ui资源,所以需要使用invoke方式同步ui
            interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象
            // Dispatcher.Invoke(interfaceUpdateHandle, new string[] { Encoding.ASCII.GetString(buf) });
            Dispatcher.Invoke(interfaceUpdataHandle, new string[] { Encoding.ASCII.GetString(buf) });

            //serialPort.Close();




        }

        private void UpdateTextBox(string text)
        {
            txtReceive.Text = text;

            String Receive = Convert.ToString(text);
            if (Receive != "")
            {
                // MessageBox.Show("receive", Receive);
                String Receive1 = Receive.Substring(0, 1);
                String Receive2 = Receive.Substring(1, 1);
                String Receive3 = Receive.Substring(2, 1);
                String Receive4 = Receive.Substring(3, 1);
                if (Receive1 == 1.ToString())
                {
                    one.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[0] = 1.ToString();
                }
                else
                {
                    one.Background = new SolidColorBrush(Colors.Red);
                    arr[0] = 0.ToString();
                }
                if (Receive2 == 1.ToString())
                {
                    two.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[1] = 1.ToString();
                }
                else
                {
                    two.Background = new SolidColorBrush(Colors.Red);
                    arr[1] = 0.ToString();
                }
                if (Receive3 == 1.ToString())
                {
                    three.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[2] = 1.ToString();
                }
                else
                {
                    three.Background = new SolidColorBrush(Colors.Red);
                    arr[2] = 0.ToString();
                }
                if (Receive4 == 1.ToString())
                {
                    four.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[3] = 1.ToString();
                }
                else
                {
                    four.Background = new SolidColorBrush(Colors.Red);
                    arr[3] = 0.ToString();
                }
                //String abc = Convert.ToString(arr);
                //MessageBox.Show("abc", abc);

                // MessageBox.Show("arr", arr);
            }
        }

最后button点击事件添加:

 private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            if (arr[0] == 0.ToString())
            {
                txtSend.Text = "0";               
                Serial();
            }
            else
            {
                txtSend.Text = "1";
                Serial();
            }
        }

        private void btnSend1_Click(object sender, RoutedEventArgs e)
        {
            if (arr[1] == 0.ToString())
            {
                txtSend.Text = "2";
                Serial();
            }
            else
            {
                txtSend.Text = "3";
                Serial();
            }
        }

        private void btnSend2_Click(object sender, RoutedEventArgs e)
        {
            if (arr[2] == 0.ToString())
            {
                txtSend.Text = "4";
                Serial();
            }
            else
            {
                txtSend.Text = "5";
                Serial();

            }
        }

        private void btnSend3_Click(object sender, RoutedEventArgs e)
        {
            if (arr[3] == 0.ToString())
            {
                txtSend.Text = "6";
                Serial();
            }
            else
            {
                txtSend.Text = "7";
                Serial();
            }
        }

要想在程序开始时就可以监听数据,在其Loaded里面添加上: Serial();
完整后台代码:

 public partial class MainWindow : Window
    {

        private SerialPort Sp = new SerialPort();
        public delegate void HandleInterfaceUpdataDelegate(string text);
        private HandleInterfaceUpdataDelegate interfaceUpdataHandle;

        String[] arr = { "0", "0", "0", "0" };//用于存储硬件上面灯状态
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //更改参数
            Sp.PortName = "COM3";
            Sp.BaudRate = 115200;
            Sp.Parity = Parity.None;
            Sp.StopBits = StopBits.One;

            Serial();
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            if (arr[0] == 0.ToString())
            {
                txtSend.Text = "0";               
                Serial();
            }
            else
            {
                txtSend.Text = "1";
                Serial();
            }
        }

        private void btnSend1_Click(object sender, RoutedEventArgs e)
        {
            if (arr[1] == 0.ToString())
            {
                txtSend.Text = "2";
                Serial();
            }
            else
            {
                txtSend.Text = "3";
                Serial();
            }
        }

        private void btnSend2_Click(object sender, RoutedEventArgs e)
        {
            if (arr[2] == 0.ToString())
            {
                txtSend.Text = "4";
                Serial();
            }
            else
            {
                txtSend.Text = "5";
                Serial();

            }
        }

        private void btnSend3_Click(object sender, RoutedEventArgs e)
        {
            if (arr[3] == 0.ToString())
            {
                txtSend.Text = "6";
                Serial();
            }
            else
            {
                txtSend.Text = "7";
                Serial();
            }
        }

        private void Serial()
        {
            Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
            if (!Sp.IsOpen)
            {
                Sp.Open();
            }
            //用字节的形式发送数据
            SendBytesData(Sp);
        }

        //发送二进制数据
        private void SendBytesData(SerialPort Sp)
        {

            byte[] bytesSend = System.Text.Encoding.Default.GetBytes(txtSend.Text);
            Sp.Write(bytesSend, 0, bytesSend.Length);

        }



        public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
           /* byte[] readBuffer = new byte[Sp.ReadBufferSize];
            Sp.Read(readBuffer, 0, readBuffer.Length);
            //Dispatcher.Invoke(interfaceUpdataHandle, new string[]{ Encoding.UTF8.GetString(readBuffer)});
            Dispatcher.Invoke(interfaceUpdataHandle, new string[] { Encoding.ASCII.GetString(readBuffer) });
            //Dispatcher.Invoke(interfaceUpdateHandle, new string[] { Encoding.ASCII.GetString(buf) });*/

            SerialPort serialPort = (SerialPort)(sender);
            System.Threading.Thread.Sleep(100);//延缓一会,用于防止硬件发送速率跟不上缓存数据导致的缓存数据杂乱
            int n = serialPort.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致  
            byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据  
            //received_count += n;//增加接收计数  
            serialPort.Read(buf, 0, n);//读取缓冲数据  
            //因为要访问ui资源,所以需要使用invoke方式同步ui
            interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象
            // Dispatcher.Invoke(interfaceUpdateHandle, new string[] { Encoding.ASCII.GetString(buf) });
            Dispatcher.Invoke(interfaceUpdataHandle, new string[] { Encoding.ASCII.GetString(buf) });

            //serialPort.Close();




        }

        private void UpdateTextBox(string text)
        {
            txtReceive.Text = text;

            String Receive = Convert.ToString(text);
            if (Receive != "")
            {
                // MessageBox.Show("receive", Receive);
                String Receive1 = Receive.Substring(0, 1);
                String Receive2 = Receive.Substring(1, 1);
                String Receive3 = Receive.Substring(2, 1);
                String Receive4 = Receive.Substring(3, 1);
                if (Receive1 == 1.ToString())
                {
                    one.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[0] = 1.ToString();
                }
                else
                {
                    one.Background = new SolidColorBrush(Colors.Red);
                    arr[0] = 0.ToString();
                }
                if (Receive2 == 1.ToString())
                {
                    two.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[1] = 1.ToString();
                }
                else
                {
                    two.Background = new SolidColorBrush(Colors.Red);
                    arr[1] = 0.ToString();
                }
                if (Receive3 == 1.ToString())
                {
                    three.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[2] = 1.ToString();
                }
                else
                {
                    three.Background = new SolidColorBrush(Colors.Red);
                    arr[2] = 0.ToString();
                }
                if (Receive4 == 1.ToString())
                {
                    four.Background = new SolidColorBrush(Colors.MediumAquamarine);
                    arr[3] = 1.ToString();
                }
                else
                {
                    four.Background = new SolidColorBrush(Colors.Red);
                    arr[3] = 0.ToString();
                }
                //String abc = Convert.ToString(arr);
                //MessageBox.Show("abc", abc);

                // MessageBox.Show("arr", arr);
            }
        }


    }

这样可以实现btn和硬件本身按钮同时控制灯亮灯灭。
若转载请注明转载处。







以上是关于WPF内实现与串口发送数据和接收数据的主要内容,如果未能解决你的问题,请参考以下文章

串口通信类,WPF

ROS串口通信简析(一)——串口发送

串口通信接收区出现多余的乱码怎么解决

C语言变成实现串口收发数据

2021-11-18 WPF上位机 87-串口通信和网口通讯

STM32 串口为啥只能接收发送的部分数据