/*
https://blog.csdn.net/weixin_42803650/article/details/115797411?spm=1001.2101.3001.6650.5&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-5-115797411-blog-103886494.235%5Ev35%5Epc_relevant_increate_t0_download_v2_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-5-115797411-blog-103886494.235%5Ev35%5Epc_relevant_increate_t0_download_v2_base&utm_relevant_index=7
在串口通迅时,虽然发送发是一次性发送一段数据的,但在接收事件中,并不是,全部接收完后再触发此事件的,
系统默认是接收到一个字节就响应接收事件(sport.ReceivedBytesThreshold = 1),为了避免接收的不完整,
自己摸索了三种方法,初学编程,也不知道方法好不好,但验证过可行。
第一种就是把 sport.ReceivedBytesThreshold 设置成你要接收的字节的长度,但这种方法不灵活,只能接收相同长度的信息。
第二种方法,就是接收到消息后,暂停一会,等消息会部接收完了再响应事件。但这种方法可能会对速度有影响。
第三种方法是发送方发出一个结束符(如\r),当接收到这个结束符后再响应事件。 if(builder.ToString().indexof("\r")>=0
*/
```csharp
private void sport_dataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(5);//暂停一会
int n = sport.BytesToRead;//
byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
sport.Read(buf, 0, n);//读取缓冲数据
builder.Clear();//清除字符串构造器的内容
this.Invoke((EventHandler)(delegate//因为要访问ui资源,所以需要使用invoke方式同步ui。
{
builder.Append(Encoding.ASCII.GetString(buf));//直接按ASCII规则转换成字符串
try
{
if (builder.ToString().Substring(0, n - 1) == "read")
{
iReader.Start();
}
else if (builder.ToString().Substring(0, n - 1) == "stop")
{
iReader.Stop();
if (isdo == false)
{
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}));
}
/*
C#中的串口通信SerialPort
什么是串口通讯
串口通讯是指外设和计算机间通过数据信号线,地线,控制线等,按位进行传输数据的一种通讯方式。
这种通讯方式使用的数据线少,在远距离通信中可以节约成本,但其传输速度比并行通讯慢。
串口是计算机上一种非常通用的设备通讯协议。大多数计算机包含两个基于RS-232的串口。
串口也是仪器仪表设备通用的通讯协议,很多GPIB兼容的设备也带有RS-232口,同时串口通信协议也可以用于获取远程设备采集的数据。
串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时也可将接受的串行数据流转换为并行的数据字符供给CPU的器件。
一般完成这种功能的电路,我们称为串行接口电路。
串行按位(bit)发送和接收字节,尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。
这里提一句,我们笔记本的USB口,它不是串口,它是所谓的U口,我们的串口如果需要插入到USB口,那么就需要一个RS-232转U口的转换器才可以。
这里需要注意下,一般我们的硬件工程师都会在自己的硬件设备都内置这个小转换设备,很方便。
C#中的串口通讯SerialPort
从.NET Framework 2.0开始,微软就默认提供了System.IO.Ports.SerialPort类,根据SerialPort类提供的简单操作步骤,可以很容易完成串口的信息收发程序,从特定的串口中接收到数据也可以进行数据的发送。
关于SerialPort类的应用也很容易,可以根据微软官方的介绍进行使用。
配置SerialPort的名称,端口号,波特率等。
打开/关闭串口
接收/发送数据
*/
```csharp
// 配置串口
```csharp
SerialPort mySerialPort = new SerialPort("COM2");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity=Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.Non;
mySerialPort.DataReceived += new SerialDataReceivedEvenHandler(DataReceive_Method);
mySerialPort.Open();
mySerialPort.Close();
// 发送数据
using System.IO.Ports;
private static void SendSampleData()
{
SerialPort port = new SerialPort(
"COM1", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.Write("Hello World");
port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
port.Close();
}
namespace SerialPortExample
{
class SerialPortProgram
{
private SerialPort port = new SerialPort("COM1",
9600, Parity.None, 8, StopBits.One);
[STAThread]
static void Main(string[] args)
{
new SerialPortProgram();
}
private SerialPortProgram()
{
Console.WriteLine("Incoming Data:");
port.DataReceived += new
SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
Application.Run();
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine(port.ReadExisting());
}
}
}
日常串口的使用多数情况是和线程进行的,一般都是在子线程中做这些耗时和重复的工作,在主线程或者界面只进行数据的展示处理即可。
在子线程的处理过程中需要特别处理串口的打开和关闭,要及时关闭串口的状态,防止出现无法捕获的异常错误。