C#实现串口通信详解

 更新时间:2024年12月02日 08:26:49   作者:小码编匠  
串口通信(Serial Communications)是指外设和计算机间通过数据信号线、地线等按位(bit)进行传输数据的一种通信方式,属于串行通信方式,能够实现远距离通信,本文给大家介绍了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;

二、串口调试工具

在对串口进行编程时候,我们要向串口发送指令,然后我们解析串口返回的指令。

在这里向大家推荐一款工具。

将要发送的指令用空格隔开,选择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;
ialPort.WriteTimeout = -1; 

pen();
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());
                  }
              }
          }
} 

至此,串口通信编程告一段落

最后

到此这篇关于C#实现串口通信详解的文章就介绍到这了,更多相关C#串口通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#使用LINQ查询操作符实例代码(一)

    C#使用LINQ查询操作符实例代码(一)

    这篇文章介绍了C#使用LINQ查询操作符的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Unity为软件添加使用有效期的具体步骤

    Unity为软件添加使用有效期的具体步骤

    今天小编遇到这样一个需求需要为软件设定一个使用有效期,当超过指定时间后,程序无法执行,实现思路并不复杂,今天小编通过本文给大家分享Unity为软件添加使用有效期的具体步骤,感兴趣的朋友一起看看吧
    2022-03-03
  • C# 添加PDF页眉/页脚的示例代码

    C# 添加PDF页眉/页脚的示例代码

    这篇文章主要介绍了C# 添加PDF页眉/页脚的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • C#排序算法之快速排序解析

    C#排序算法之快速排序解析

    这篇文章主要为大家详细介绍了C#排序算法之快速排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-01-01
  • C# WinForm捕获未处理的异常实例解析

    C# WinForm捕获未处理的异常实例解析

    这篇文章主要介绍了C# WinForm捕获未处理的异常,包括了常见的未捕获的异常、UI线程异常、非UI线程异常等,非常实用,需要的朋友可以参考下
    2014-09-09
  • c# 如何将字符串转换为大写或小写

    c# 如何将字符串转换为大写或小写

    这篇文章主要介绍了c# 如何将字符串转换为大写或小写,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • C#实现逐行读取和写入文件的方法

    C#实现逐行读取和写入文件的方法

    这篇文章给大家介绍了使用C#语言实现同样的功能,即从输入文件中读取每行数据,然后将每行字段组合成SQL插入脚本,然后逐行写入另外一个空白文件中,感兴趣的朋友可以参考下
    2024-01-01
  • Unity实现攻击范围检测并绘制检测区域

    Unity实现攻击范围检测并绘制检测区域

    这篇文章主要介绍了Unity实现攻击范围检测并绘制检测区域,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#实现电子邮件发送功能(支持普通文本,HTML和附件)

    C#实现电子邮件发送功能(支持普通文本,HTML和附件)

    在日常开发或自动化任务中,发送电子邮件仍然是最常用的数据传递方式之一,本文我们就来讲讲如何使用 C# 发送包含普通文本,HTML 正文以及附件的电子邮件吧
    2025-07-07
  • C#读取写入文件的3种方式示例代码

    C#读取写入文件的3种方式示例代码

    最近操作文件频繁,所以这篇文章主要给大家介绍了关于C#读取写入文件的3种方式,文中通过实例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友可以参考下
    2022-06-06

最新评论