串口通讯协议——SerialPort详解

_Csharp 2024-09-14 12:07:11 阅读 78

目录

串口通讯

硬件流控制(RTS/CTS)

SerialPort的使用

SerialPort常用属性

SerialPort常用方法

SerialPort事件

创建SerialPort对象以及配置参数

方式一

方式二

SerialPort实现串口通信完整例子


串口通讯

串行通信作为计算机通信方式之一,主要起到主机与外设以及主机之间的数据传输作用,串行通信具有传输线少、成本低的特点,主要适用于近距离的人-机交换、实时监控等系统通信工作当中,借助于现有的电话网也能实现远距离传输,因此串行通信接口是计算机系统当中的常用接口。

硬件流控制(RTS/CTS)

RTS/CTS流控制是硬件流控制的一种,需要按下图连线:

串口设备A给串口设备B发送数据。B忙不过来时(B的串口输入缓冲区快满了)会设置自己的RTS为低电平,这样A的CTS也变为低电平。A发现自己的CTS为低电平后,会停止发送数据;B的串口输入缓冲区快空时,会设置自己的RTS为高电平,这样A的CTS也变为高电平。A发现自己的CTS为高电平后,会继续发送数据。

相同的道理,DTR/DSR也可以做硬件流控制。

为什么打开串口时需要设置DTR、RTS为高电平呢?原因就在于:如果对方设置了硬件流控制,而这边的DTR、RTS为低电平,那么对方就不会给这边发送数据。

SerialPort的使用

SerialPort是一个串口传输的一个非常方便的控件,对从事上位机测试的人是一个很好的控件,很多做嵌入式开发的人,他们的大部分界面都是用C#写的,难免会用到这个控件

SerialPort常用属性

PortName 获取或设置通信端口,包括但不限于所有可用的 COM 端口(设置使用哪个串口)
BaudRate 设置或获取波特率
StopBits 设置或获取数据停止位
DataBits 设置或获取数据位
Parity 获取或设置奇偶校验检查协议
BytesToRead 获取缓冲区中读到数据的长度
ReadTimeout 或者或设置读取操作的超时时间
WriteTimeout 或者或设置写入操作的超时时间

SerialPort常用方法

public static string[] GetPortNames 获取当前计算机的串行端口名的数组。
Open 开串口连接
Close 关闭串口连接
Read 从 SerialPort 输入缓冲区中读取数据
Write 向 SerialPort 写入数据

Open`​ 打开串口连接打开后一般要设置`DtrEnable、RtsEnable`​为true,具体原因见下文

      xxx.Open();

      xxx.DtrEnable = true;

      xxx.RtsEnable = true;

SerialPort事件

DataReceived 指示已通过由 SerialPort 对象表示的端口接收了数据
ErrorReceived 指示由 SerialPort 对象表示的端口上发生了错误。

创建SerialPort对象以及配置参数

方式一

通过对应的属性进行配置

<code>private SerialPort serialPort = new SerialPort();

public SerialPortExample()

{

serialPort.PortName = "COM3"; // 设置串口名称

serialPort.BaudRate = 9600; // 设置波特率

serialPort.Parity = Parity.None; // 设置奇偶校验

serialPort.DataBits = 8; // 设置数据位数

serialPort.StopBits = StopBits.One; // 设置停止位

serialPort.Handshake = Handshake.None; // 设置握手协议

serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); // 接收到数据时的事件

}

方式二

通过构造函数进行配置

SerialPort port = new SerialPort("COM2",9600,Parity.None,8,(StopBits)1);

SerialPort实现串口通信完整例子

public partial class Form1 : Form

{

// 创建一个全局的串口对象

readonly SerialPort port = new SerialPort();

public Form1()

{

InitializeComponent();

// 对串口添加一下配置

// 单位是bit/s,常见的波特率1s是9600bit,1Byte是8bit 9600bit/8 = 1200字节,也就是1s发送1200个字节

// 注意波特率不能太大 也不能太小,如果太大了传输的数据不稳定,如果俩端的波特率不一致会导致数据不一致,如果太小了反应太慢

port.BaudRate = 9600; // 设置波特率

// 2 StopBits停止位

// StopBits是一个枚举类型,可选择有1位,1.5位,2位,默认值是1位

port.StopBits = StopBits.One;

// 3 DataBits 数据位: 通信中真正的有效信息,数据位可以双方通过约定进行控制 一般可以5、6/7/8

// 默认值是8位

port.DataBits = 8;

// 4 Parity 奇数校检位 只占1位,指定是逻辑高位是奇数或者偶数个,高位就是1,地位就是0

// 可取值有Parity.None 不采用校检

// Parity.Odd 奇数校检,保证传输过程汇总高位个数是奇数个

// Parity.Even 偶数校检,保证传输过程中高位个数是偶数个

port.Parity = Parity.None;

// 5 PortName设置连接串口名

port.PortName = "COM1";

// 6 Encoding 编码格式,设置显示以什么格式显示

// 默认16进制格式

port.Encoding = Encoding.Default;

// 必须配置的 波特率 和 设置串口

// 11 接收数据的事件

port.DataReceived += Port_DataReceived;

}

bool isDefault = true; // 代表编码方式 true代表默认编码

/// <summary>

/// 接收数据的事件

/// </summary>

/// <param name="sender"></param>code>

/// <param name="e"></param>code>

private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)

{

// 接收数据并且显示,

// 13 port.BytesToRead 从缓存区读取数据的长度

byte[] bs = new byte[port.BytesToRead];

// 14 Read 从缓存区读取数据

port.Read(bs, 0, bs.Length);

string value = null;

// 以哪种编码方式展示数据

this.Invoke((EventHandler)delegate

{

if (isDefault)

{

// 十六进制

foreach (var b in bs)

{

value += " " + b.ToString("X"); //X代表16进制

}

}

else

{

// GetEncoding("gb2312") 国标2312编码格式

value = Encoding.GetEncoding("gb2312").GetString(bs);

}

this.richTextBox1.AppendText(value+"\r\n");

this.richTextBox1.ScrollToCaret();

// DiscardInBuffer 清空缓存区

port.DiscardInBuffer(); // 清空缓存区

});

}

/// <summary>

/// 打开串口

/// </summary>

/// <param name="sender"></param>code>

/// <param name="e"></param>code>

private void button1_Click(object sender, EventArgs e)

{

// 7 IsOpen 当前串口是否是打开状态,

// true 为打开状态

// false 关闭状态

if (!port.IsOpen) // 没打开

{

// 8 打开串口

port.Open();

// 9 打开之后 要设置一下俩个属性为true

// DtrEnable 为true,启用数据终端就绪,发送一个dtr信号。

port.DtrEnable = true;

// RtsEnable 为true,证明请求可以发送了,发送一个rts信号

port.RtsEnable = true;

button1.Text = "关闭";

}

else

{

button1.Text = "打开";

// 10 关闭串口

port.Close();

}

}

/// <summary>

/// 发送数据

/// </summary>

/// <param name="sender"></param>code>

/// <param name="e"></param>code>

private void button3_Click(object sender, EventArgs e)

{

byte[] bs = Encoding.UTF32.GetBytes(this.textBox1.Text);

// 12 Write 发送数据

port.Write(bs,0,bs.Length);

}

/// <summary>

/// 检测串口

/// </summary>

/// <param name="sender"></param>code>

/// <param name="e"></param>code>

private void DetectionSerialButton_Click(object sender, EventArgs e)

{

// 获取电脑下所有串口端口

SerialList = System.IO.Ports.SerialPort.GetPortNames();

if (SerialList.Length!=0)

{

this.SerialComboBox.DataSource = SerialList;

this.SerialComboBox.SelectedIndex = 0;

}

else

{

MessageBox.Show("未获取到串口!!!","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);

}

}

}

本文部分借鉴网络,如有侵权请联系删除!!!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。