博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#串口通信总结
阅读量:7049 次
发布时间:2019-06-28

本文共 3857 字,大约阅读时间需要 12 分钟。

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

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

转载于:https://www.cnblogs.com/vmyspace/archive/2012/03/21/2409489.html

你可能感兴趣的文章
聊聊spring cloud的HystrixAutoConfiguration
查看>>
Android字节码插桩采坑笔记
查看>>
iOS中使用Protocol Buffer
查看>>
大神解析-ZooKeeper基本原理
查看>>
网络层安全认知
查看>>
有趣的二进制2—高效位运算
查看>>
Hive 调优
查看>>
带你五步学会Vue SSR
查看>>
Angular4中自定义管道
查看>>
Android NDK开发之旅26 C++ STL
查看>>
从源码全面剖析 React 组件更新机制
查看>>
MySQL 去重SQL
查看>>
问题备忘: 服务器重启后,导致freeswitch的internal的profile无法启动
查看>>
Java虚拟机之Class类文件结构
查看>>
Service销毁流程
查看>>
Elasticsearch的入门使用
查看>>
An error occurred uploading to the iTunes Store.
查看>>
Mac HomeBrew国内镜像安装方法
查看>>
《Android源码设计模式解析与实战》——面向对象的六大原则的图片加载器源码...
查看>>
神奇的 defineProperty
查看>>