C#,winform
关于串口接收数据更新和显示,遇到了两个问题,
1、我有多个页面,然后页面8有连接串口的设置,现在是遇到了checkBox1_CheckedChanged订阅事件SerialPort1_DataReceived失败,没法接收数据
2、之前直接把SerialPort1_DataReceived里面的代码放在checkBox1_CheckedChanged就可以接收到数据,但是会存在另一个问题,只有最开始接收的数据可以显示,更改串口发送的值,接收SetMsg框和数据不更新,只有关闭连接按键,再重新点击连接按键才会更新接收的数据
ps:modbus的ReadHoldingRegisters(),ReadInputRegisters()等等代码没贴
页面8

代码段
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Windows.Forms;
using Modbus.Device; // 引入 NModbus 库
using Modbus.Message;
using Modbus.Data;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Markup;
using System.Threading;
using System.Diagnostics;
namespace WindowsFormsApp1
{
public partial class UserControl8 : UserControl
{
public UserControl8()
{
InitializeComponent();
}
/// 私有ModbusRTU主站字段
private static ModbusMaster master1;
private static IModbusMaster master;
/// 串口设置
private void UserControl8_Load(object sender, EventArgs e)
{
//串口的COM口设置
for (int i = 1; i < 20; i++)
{
comboBox1.Items.Add("COM" + i.ToString());
}
//默认串口值是检测到的串口
string[] portname_com = SerialPort.GetPortNames();
string com = String.Join(",", portname_com);
if (portname_com.Length > 0)
{
// 将第一个可用的串口设置为 comboBox1 的默认选中项
comboBox1.SelectedItem = portname_com[0];
}
//串口的波特率设置
int[] numbers = { 1200, 2400, 4800, 9600, 14400 ,19200,38400,43000,57600,76800,115200,128000,230400,256000,460800,921600,1382400 };
comboBox2.DataSource = numbers;
comboBox2.DisplayMember = "ToString";
//地址最小0,最大256
nudSlaveID.Minimum = 0;
nudSlaveID.Maximum = 256;
// nudStartAdr.Minimum = 0;
// nudLength.Minimum = 1;
/*
for (int i = 0; i < 256; i++)
{
string s = string.Format("0x{0:X2}", i);
nudSlaveID.Items.Add(s);
}
*/
string[] numbers4 = { "RTU", "ASCII" };
comboBox3.DataSource = numbers4;
comboBox3.DisplayMember = "ToString";
}
//串口接收数据
private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
switch (PublicValue.code) {
case 0x03:
this.Invoke((MethodInvoker)delegate { SetMsg(ReadHoldingRegisters().ToList());});
PublicValue.UpdateResult0x03(ReadHoldingRegisters());
break; // "读取保持型寄存器"
case 0x04:
this.Invoke((MethodInvoker)delegate { SetMsg(ReadInputRegisters().ToList()); });
PublicValue.UpdateResult0x04(ReadInputRegisters());
break; // "读取输入寄存器"
case 0x10:
WriteArrayRegister();
break; // "写入多个寄存器"
case 0x11:
QuerySetupData();
break; // "查询设置数据"
case 0x12:
QueryHistory();
break; // "查询历史记录"
default:
break;
}
}
catch (Exception ex)
{
this.Invoke((MethodInvoker)delegate
{
MessageBox.Show($"接收数据时发生错误: {ex.Message}");
});
}
}
//连接串口和订阅串口接收数据
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
label5.Text = PublicValue.code.ToString();
try
{
// 波特率
serialPort1.BaudRate = (int)comboBox2.SelectedItem;
// 数据位
serialPort1.DataBits = 8;
serialPort1.PortName = comboBox1.Text;
// 一个停止位
serialPort1.StopBits = System.IO.Ports.StopBits.One;
// 无奇偶校验位
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.ReadTimeout = 100;
master1 = ModbusSerialMaster.CreateRtu(serialPort1);
// 打开串口成功后,订阅 DataReceived 事件
serialPort1.DataReceived += SerialPort1_DataReceived;
serialPort1.Open();
if (!serialPort1.IsOpen)
{
MessageBox.Show("端口打开失败");
return;
}
else
{
MessageBox.Show("端口" + comboBox1.Text + "打开成功\r\n");
checkBox1.Text = "关闭";
}
}
catch (Exception ex)
{
serialPort1.Dispose();
MessageBox.Show($"打开串口时发生错误: {ex.Message}");
}
}
else
{
try
{
// 关闭串口前,取消订阅 DataReceived 事件
serialPort1.DataReceived -= SerialPort1_DataReceived;
serialPort1.Close();
checkBox1.Text = "打开";
}
catch (Exception ex)
{
MessageBox.Show($"关闭串口时发生错误: {ex.Message}");
}
}
}
/// <summary>
/// 界面显示读取结果
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="result"></param>
private void SetMsg<T>(List<T> result)
{
string msg = string.Empty;
result.ForEach(m => msg += $"{m} ");
rbxRWMsg.Text = msg.Trim();
}
}
}