串口通信

# 串口通信

介绍

这篇随笔主要介绍串口通信.

串口通信标准一般分为:RS232和RS485

效果图(原生接口实现)

image-20200229103904898

原生接口实现

1、串口打开和关闭

        /// <summary>
        /// 串口打开与关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (btnOpen.Text == "打开串口")
            {
                try
                {
                    if (!com.IsOpen)
                    {
                        com.PortName = cmbPort.Text;
                        com.BaudRate = int.Parse(cmbBaudRate.Text);
                        com.DataBits = int.Parse(cmbDataBits.Text);
                        switch (cmbStopBits.SelectedIndex)                        {
                            case 0:
                                com.StopBits = StopBits.One; break;
                            case 1:
                                com.StopBits = StopBits.Two; break;
                            case 2:
                                com.StopBits = StopBits.OnePointFive; break;
                            case 3:                             
                                com.StopBits = StopBits.None; break;
                        }
                        switch (cmbParity.SelectedIndex)
                        {
                            case 0: com.Parity = Parity.None; break;
                            case 1: com.Parity = Parity.Odd; break;
                            case 2: com.Parity = Parity.Even; break;
                        }

                        com.Open();//打开串口
                    }
                    btnOpen.Text = "关闭串口";
                    txtStatus.Text = "串口已打开!";
                    btnSend.Enabled = true;
                    if (rbAck.Checked)
                        btnReceive.Enabled = true; //应答模式,接收按钮有效
                }
                catch
                { txtStatus.Text = "串口打开错误或串口不存在!"; }
            }
            else //关闭串口

                try
                {
                    if (com.IsOpen)
                       com.Close(); //关闭串口
                    btnOpen.Text = "打开串口";
                    txtStatus.Text = "串口已关闭!";
                    btnSend.Enabled = false ;
                    if (rbAck.Checked)
                        btnReceive.Enabled = false; //应答模式,接收按钮有效
                }
                catch
                { txtStatus.Text = "串口关闭错误或串口不存在!"; }
        }

2、应答模式下串口接收数据

        /// <summary>
        /// 串口接收数据,应答模式时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReceive_Click(object sender, EventArgs e)
        {
            try
             {
                 //应答模式
                int count = com.BytesToRead;
                byte[] readBuffer = new byte[count];
                com.Read(readBuffer, 0, count);
                if (chkRecHex.Checked)
                   txtReceive.Text = getStringFromBytes(readBuffer);  //转十六进制
                else
                   txtReceive.Text = Encoding.Default.GetString(readBuffer);  //字母、数字、汉字转换为字符串 
               
            }
            catch (Exception err)
            { txtStatus.Text = err.ToString(); }
        }

3、响应模式下串口接受数据事件

        /// <summary>
        /// 响应模式时,串口接收数据事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {  
            try
           {
               int count = com.BytesToRead;
               byte[] readBuffer = new byte[count];
               com.Read(readBuffer, 0, count);
               string strReceive="";
               if(chkRecHex.Checked)
                  strReceive = getStringFromBytes(readBuffer);  //转十六进制
               else
                 strReceive = Encoding.Default.GetString(readBuffer);  //字母、数字、汉字转换为字符串          
               this.Invoke(new showReceiveDelegate(doShowReceive), strReceive);

             }
           catch (Exception err)
             { txtStatus.Text = err.ToString(); }

        }

SerialPortLib实现

1、打开Visual Studio,在Nuget中安装SerialPortLib

image-20200229102621922

2、初始化端口和注册事件

            SerialPortLib.SerialPortInput serialPortInput = new SerialPortInput();
            try
            {
                serialPortInput.SetPort("COM1", 9600, StopBits.One, Parity.None,DataBits.Eight);//初始化串口:串口名,波特率,停止位,奇偶校验,数据位
                serialPortInput.Connect();
                serialPortInput.ConnectionStatusChanged += SerialPortInput_ConnectStatusChange;
                serialPortInput.MessageReceived += SerialPortInput_MessageReceive;
            }
            catch
            {
                MessageBox.Show("串口初始化失败");
            }

3、事件方法

        void SerialPortInput_ConnectStatusChange(object sender, ConnectionStatusChangedEventArgs args)
        {
            if(serialPortInput.IsConnected)
            {
                MessageBox.Show("Serial Open");
            }
            else
            {
                MessageBox.Show("Serial Close");
            }
        }
        void SerialPortInput_MessageReceive(object sender, MessageReceivedEventArgs args)
        {
            string a = System.Text.Encoding.UTF8.GetString(args.Data);
            MessageBox.Show(a);
        }

4、其他方法

            byte[] a = System.Text.Encoding.UTF8.GetBytes("1234");
            serialPortInput.SendMessage(a);
            serialPortInput.Disconnect();

格式转化方法

        /// <summary>
        /// 把十六进制格式的字符串转换成字节数组。
        /// </summary>
        /// <param name="pString">要转换的十六进制格式的字符串</param>
        /// <returns>返回字节数组。</returns>
        public static byte[] getBytesFromString(string pString)
        {
            string[] str = pString.Split(' ');     //把十六进制格式的字符串按空格转换为字符串数组。
            byte[] bytes = new byte[str.Length];     //定义字节数组并初始化,长度为字符串数组的长度。
            for (int i = 0; i < str.Length; i++)     //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量。
                bytes[i] = Convert.ToByte(Convert.ToInt32(str[i], 16));
            return bytes;     //返回字节数组。
        }

        /// <summary>
        /// 把字节数组转换为十六进制格式的字符串。
        /// </summary>
        /// <param name="pByte">要转换的字节数组。</param>
        /// <returns>返回十六进制格式的字符串。</returns>
        public static string getStringFromBytes(byte[] pByte)
        {
            string str = "";     //定义字符串类型临时变量。
            //遍历字节数组,把每个字节转换成十六进制字符串,不足两位前面添“0”,以空格分隔累加到字符串变量里。
            for (int i = 0; i < pByte.Length; i++)
                str += (pByte[i].ToString("X").PadLeft(2, '0') + " ");
            str = str.TrimEnd(' ');     //去掉字符串末尾的空格。
            return str;     //返回字符串临时变量。
        }

无硬件串口测试方法

1、下载虚拟串口工具VSPD,并安装

image-20200229104710784

2、创建串口后打开串口调试工具(A)和程序(B)分别连接COM1和COM2

3、此时A和B就能够互相通信了。也可在VSPD看发送和接受的字节数:Sent和Received。

源码地址

Git:https://gitee.com/PErobin/Socket.git

SVN:svn://gitee.com/PErobin/Socket

posted @ 2020-02-29 11:12  sky七月凉  阅读(585)  评论(0编辑  收藏  举报