• C# 串口通信总结


    C# 串口通信总结

     
    我们知道对于 
     
     标准DLL,可以采用DllImport进行调用。例如:
     [DllImport("KMY350X.dll")]
            private static extern int OpenPort(int PortNum, int BaudRate);

    如果一些厂家比较懒的话,没有提供相应的dll,我们只能对它进行串口通信编程了。以前从没接触过串口编程,最近在一个项目中有几个地方都需要采用串口通信,跟公司一个老手请教后,感觉学到了很多东西,特在此做个总结:

         

         一:首先我们来认识下什么是串口:

    右键 我的电脑-管理-设备管理器-端口,选择一个端口,点击属性。

            

    我们可以看到该串口的属性,在C#中我们使用SerialPort类来表示串口

    复制代码
                ConfigClass config = new ConfigClass();
        comm.serialPort.PortName = config.ReadConfig("SendHealCard");
                //波特率
                comm.serialPort.BaudRate = 9600;
                //数据位
                comm.serialPort.DataBits = 8;
                //两个停止位
                comm.serialPort.StopBits = System.IO.Ports.StopBits.One;
                //无奇偶校验位
                comm.serialPort.Parity = System.IO.Ports.Parity.None;
                comm.serialPort.ReadTimeout = 100;
                comm.serialPort.WriteTimeout = -1;
    复制代码

            二:串口调试工具:

    在对串口进行编程时候,我们要向串口发送指令,然后我们解析串口返回的指令。在这里向大家推荐一款工具。

            串口调试助手.exe

            

             

    将要发送的指令用空格隔开,选择HEX显示为放回的字符串。

           

    三:正式编程:

           

    编写Comm类:

    复制代码
         public class Comm   
         {
            public delegate void EventHandle(byte[] readBuffer);
            public event EventHandle DataReceived;

            public SerialPort serialPort;
            Thread thread;
            volatile bool _keepReading;

            public Comm()
            {
                serialPort = new SerialPort();
                thread = null;
                _keepReading = false;
            }

            public bool IsOpen
            {
                get 
                {
                    return serialPort.IsOpen;
                }
            }        

            private void StartReading()
            {
                if (!_keepReading)
                {
                    _keepReading = true;
                    thread = new Thread(new ThreadStart(ReadPort));
                    thread.Start();
                }
            }

            private void StopReading()
            {
                if (_keepReading)
                {
                    _keepReading = false;
                    thread.Join();
                    thread = null;                
                }
            }

            private void ReadPort()
            {
                while (_keepReading)
                {
                    if (serialPort.IsOpen)
                    {
                        int count = serialPort.BytesToRead;
                        if (count > 0)
                        {
                            byte[] readBuffer = new byte[count];
                            try
                            {
                                Application.DoEvents();
                                serialPort.Read(readBuffer, 0, count);
                                if(DataReceived != null)
                                    DataReceived(readBuffer);
                                Thread.Sleep(100);
                            }
                            catch (TimeoutException)
                            {
                            }
                        }
                    }
                }
            }

            public void Open()
            {
                Close();            
                serialPort.Open();
                if (serialPort.IsOpen)
                {
                    StartReading();
                }
                else
                {
                    MessageBox.Show("串口打开失败!");
                }
            }

            public void Close()
            {
                StopReading();
                serialPort.Close();
            }

            public void WritePort(byte[] send, int offSet, int count)
            {
                if (IsOpen)
                {
                    serialPort.Write(send, offSet, count);
                }
            }
        }
    复制代码

       

    注册串口:

         

    复制代码
                Comm 
     
      comm = new Comm();
                ConfigClass config = new ConfigClass();
                comm.serialPort.PortName = config.ReadConfig("SendHealCard");
                //波特率
                comm.serialPort.BaudRate = 9600;
                //数据位
                comm.serialPort.DataBits = 8;
                //两个停止位
                comm.serialPort.StopBits = System.IO.Ports.StopBits.One;
                //无奇偶校验位
                comm.serialPort.Parity = System.IO.Ports.Parity.None;
                comm.serialPort.ReadTimeout = 100;
        comm.serialPort.WriteTimeout = -1; 
         
          comm.Open();
                if (comm.IsOpen)
                {
                    comm.DataReceived += new Comm.EventHandle(comm_DataReceived);
                }
    复制代码

    发送指令:

          

    复制代码
            /// <summary>
    /// 发卡到机口
            /// </summary>
            private void SendCardToOut()
            {
                is_read_card = false;
                sendCardToOut = true;
                byte[] send = { 0x02, 0x46, 0x43, 0x34, 0x03, 0x30 };
                if (comm.IsOpen)
                {
                    comm.WritePort(send, 0, send.Length);
                }
            } 
    复制代码

    收到指令,并解析:

         

    复制代码
            
     
       void comm_DataReceived(byte[] readBuffer1)
     {
                //log.Info(HexCon.ByteToString(readBuffer));
                if (readBuffer1.Length == 1)
                {
                    receive = HealCardClass.ByteToString(readBuffer1);
                    string str = "06";
                    if (string.Equals(receive.Trim(), str, StringComparison.CurrentCultureIgnoreCase))
                    {
                        try
                        {
                            if (is_read_card)
                            {
                                byte[] send = new byte[1];
                                send[0] = 0x05;
                                comm.WritePort(send, 0, send.Length);
                                Thread.Sleep(500);
                                comm.DataReceived -= new Comm.EventHandle(comm_DataReceived);
                                InitReadComm();
                            }
                            if (sendCardToOut)
                            {
                                byte[] send = new byte[1];
                                send[0] = 0x05;
                                comm.WritePort(send, 0, send.Length);


                                readComm.DataReceived -= new Comm.EventHandle(readComm_DataReceived);
                                readComm.Close();

                                log.Info("发卡完成!");
                                lblMsg.Text = "发卡成功!";
                                lblSendCardMsg.Text = "发卡完成,请收好卡!";
                                timer1.Tick -= new EventHandler(timer1_Tick);
                                PlaySound();
                                this.btnOK.Enabled = true;


                            }
                        }
                        catch (Exception ex)
                        {
                            log.Info(ex.ToString());
                        }
                    }
                }
      } 
  • 相关阅读:
    常用的文件查看命令
    Linux常用快捷按键
    寒冬储粮
    创建型模式:抽象工厂
    创建型模式:工厂方法
    创建型模式:单例模式
    开闭原则
    迪米特法则
    接口隔离原则
    依赖倒置原则
  • 原文地址:https://www.cnblogs.com/zxtceq/p/5482422.html
Copyright © 2020-2023  润新知