C#串口通信01  简单入门:读取信息

C#串口通信01 简单入门:读取信息

Amiron 326 2022-04-24

前言

最近在用c#写上位机软件,将自己入门的过程记录下来。入门嘛,实操很重要,先弄一个例子来尝尝鲜。

环境

IDE: VS 2019
环境: .NET Core 3.1
依赖: System.IO.Ports、thinger.DataConvertLib
测试工具: Modbus Slave

引入依赖

在.NET Core 3.1中SerialPort不是自带的库了,需要自行引入;thinger.DataConvertLib是一个数据转换库,在码云上开源;推荐使用Nuget安装。

结构

SerialPortDemo-01
└── MarinForm.cs
└── Program.cs

界面

简单的测试界面

控件初始化

private void MainForm_Load(object sender, EventArgs e)
{
	// 获取当前可识别的串口
	string[] port = System.IO.Ports.SerialPort.GetPortNames();

	// 初始化界面
	comboBoxPortName.Items.AddRange(port);
	// 如果有数据显示第0个
	comboBoxPortName.SelectedIndex = comboBoxPortName.Items.Count > 0 ? 0 : -1;

	comboBoxBaudRate.Items.Add(1200);
	comboBoxBaudRate.Items.Add(4800);
	comboBoxBaudRate.Items.Add(9600);
	comboBoxBaudRate.Items.Add(14400);
	comboBoxBaudRate.Items.Add(19200);
	comboBoxBaudRate.Items.Add(38400);

	comboBoxBaudRate.SelectedItem = 9600;
}

发送读取命令

private void buttonRead_Click(object sender, EventArgs e)
{
	try {
                // 0x01 -- 从机地址;  0x03 -- 功能码; 0x00 -- 高位起始地址
                // 0x00 -- 低位起始地址; 0x00 -- 高位读取寄存器个数
                // 0x09 -- 低位读取寄存器个数
                // 0x85 0xCC -- 校验位

		byte[] request = new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x9, 0x85, 0xCC };
                //byte[] request = new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x64, 0x44, 0x21 }
		textBoxLog.AppendText("发送请求:" + 
					StringLib.GetHexStringFromByteArray(request) + "\r\n");
		serialPort.Write(request, 0, request.Length);
	} catch(Exception ex)
	{
		MessageBox.Show(ex.Message);
	}

}

打开串口

private void buttonOpen_Click(object sender, EventArgs e)
{
	try
	{
		if(!open)
		{
                        // 订阅串口接收事件
			serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPortDataReceived);
			serialPort.PortName = comboBoxPortName.Text;
			serialPort.BaudRate = int.Parse(comboBoxBaudRate.Text);
			serialPort.DataBits = 8;
			serialPort.StopBits = StopBits.One;
			serialPort.Parity = Parity.None;
			serialPort.Open();

			buttonOpen.Text = "关闭串口";
			open = true;
		}
		else
		{
			serialPort.Close();

			buttonOpen.Text = "打开串口";
			open = false;
		}

	}
	catch (Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}

接收事件

private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
	try
	{
		serialPort = (SerialPort)sender;
		byte[] bytebuffer = new byte[serialPort.BytesToRead];
		serialPort.Read(bytebuffer, 0, bytebuffer.Length);
                
                // 接收事件与界面并不是同一个线程;所以需要用Invoke()方法同步更新界面
		Invoke(new Action(() => textBoxLog
			 .AppendText("收到响应:" + StringLib.GetHexStringFromByteArray(bytebuffer) + "\r\n")));
	}
	catch (Exception)
	{
		throw;
	}
}

测试

启动Modbus Slave

使用Modbus Slave连接到虚拟串口中,并开启100个寄存器作为测试使用。
Modbus Slave

运行程序

读9个寄存器值

源码

码云
封面


# c#