zoukankan      html  css  js  c++  java
  • 串口通信

    串口通信

    介绍

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

    串口通信标准一般分为: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

  • 相关阅读:
    《数据结构》第1章:绪论
    《计算机网络》第1章:计算机网络体系结构
    笔记迁移至:语雀
    最大似然估计和最大后验概率
    深度学习之最大似然估计
    k折交叉验证(matlab和python程序实现)
    matlab下打乱数组顺序
    线性回归
    梯度算法的Matlab实现
    梯度下降法
  • 原文地址:https://www.cnblogs.com/aqyl/p/12381931.html
Copyright © 2011-2022 走看看