csharp
using System;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;
namespace SerialScaleTester
{
public partial class MainForm : Form
{
private SerialPort _serialPort;
private delegate void UpdateUIHandler(string text);
private const string STX = "\x02";
private const string ETX = "\x03";
public MainForm()
{
InitializeComponent();
InitializeComponents();
RefreshComPorts();
}
#region 界面初始化
private void InitializeComponents()
{
this.Size = new System.Drawing.Size(600, 400);
this.Text = "串口电子秤测试程序 v1.2";
// 串口配置组
grpSerialConfig.Controls.Add(new Label { Text = "COM端口:", Location = new System.Drawing.Point(10, 20) });
cmbComPorts = new ComboBox { Location = new System.Drawing.Point(100, 15), Width = 120 };
grpSerialConfig.Controls.Add(cmbComPorts);
cmbBaudRate = new ComboBox { Location = new System.Drawing.Point(230, 15), Width = 80, SelectedIndex = 3 };
cmbBaudRate.Items.AddRange(new object[] { 2400, 4800, 9600, 19200 });
grpSerialConfig.Controls.Add(cmbBaudRate);
btnOpenClose = new Button { Text = "打开串口", Location = new System.Drawing.Point(320, 10), Width = 100 };
btnOpenClose.Click += BtnOpenClose_Click;
grpSerialConfig.Controls.Add(btnOpenClose);
// 数据显示组
txtData.Receive = new EventHandler(DataReceivedHandler);
txtData.ScrollBars = ScrollBars.Both;
txtData.Font = new Font("Consolas", 12);
}
#endregion
#region 串口操作
private void RefreshComPorts()
{
cmbComPorts.Items.Clear();
cmbComPorts.Items.AddRange(SerialPort.GetPortNames());
if (cmbComPorts.Items.Count > 0) cmbComPorts.SelectedIndex = 0;
}
private void BtnOpenClose_Click(object sender, EventArgs e)
{
try
{
if (!_serialPort.IsOpen)
{
_serialPort.PortName = cmbComPorts.Text;
_serialPort.BaudRate = int.Parse(cmbBaudRate.Text);
_serialPort.DataBits = 8;
_serialPort.StopBits = StopBits.One;
_serialPort.Parity = Parity.None;
_serialPort.Handshake = Handshake.None;
_serialPort.DataReceived += SerialPort_DataReceived;
_serialPort.Open();
btnOpenClose.Text = "关闭串口";
txtStatus.Text = "已连接:" + _serialPort.PortName;
}
else
{
_serialPort.Close();
btnOpenClose.Text = "打开串口";
txtStatus.Text = "未连接";
}
}
catch (Exception ex)
{
MessageBox.Show($"错误:{ex.Message}", "异常提示");
}
}
#endregion
#region 数据处理
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
string rawData = _serialPort.ReadExisting();
string parsedData = ParseScaleData(rawData);
if (!string.IsNullOrEmpty(parsedData))
{
this.Invoke(new UpdateUIHandler(UpdateDisplay), parsedData);
}
}
catch (TimeoutException) { }
}
private string ParseScaleData(string data)
{
try
{
// 移除控制字符
data = data.Replace(STX, "").Replace(ETX, "");
// 解析重量数据(示例协议:STX+重量+ETX)
if (data.Length >= 6 && data.StartsWith("STX"))
{
string weightStr = data.Substring(3, 5);
decimal weight = decimal.Parse(weightStr) / 100; // 假设小数点后两位
return $"{DateTime.Now:HH:mm:ss} - 当前重量:{weight:F2} kg";
}
return null;
}
catch
{
return null;
}
}
private void UpdateDisplay(string text)
{
txtData.AppendText(text + Environment.NewLine);
txtData.ScrollToCaret();
}
#endregion
#region 界面控件
private ComboBox cmbComPorts;
private ComboBox cmbBaudRate;
private Button btnOpenClose;
private TextBox txtData = new TextBox { Dock = DockStyle.Fill, Multiline = true };
private Label txtStatus = new Label { Dock = DockStyle.Bottom, Text = "就绪" };
#endregion
}
}
核心功能说明
- 串口配置 支持COM端口自动检测 波特率选择(2400/4800/9600/19200) 数据位/停止位/校验位自动配置
- 数据解析 自动过滤控制字符(STX/ETX) 提取有效数据段 重量值格式化(支持小数点后两位)
- 异常处理 超时自动重试 数据校验机制 异常捕获提示
使用说明
-
界面操作 点击"刷新"按钮获取可用COM端口 选择对应端口和波特率 点击"打开串口"开始通信
-
数据展示 实时显示接收数据 自动滚动最新记录 时间戳标记
-
协议扩展
csharp// 修改ParseScaleData方法以适应不同协议 private string ParseScaleData(string data) { // 示例:耀华XK3190协议解析 if (data.Contains("GS,")) { string[] parts = data.Split(','); decimal weight = decimal.Parse(parts[1]) / 10; return $"重量:{weight:F1} kg"; } return null; }
参考代码 C# 串口电子秤测试程序源码 www.youwenfan.com/contentcso/93751.html
高级功能建议
-
数据保存
csharpprivate void SaveData(string text) { string logPath = Path.Combine(Application.StartupPath, "scale_log.txt"); File.AppendAllText(logPath, text + Environment.NewLine); } -
校准功能
csharpprivate void Calibrate() { _serialPort.WriteLine("CALIBRATE"); // 发送校准指令 } -
多设备支持
csharpprivate Dictionary<string, SerialPort> _devices = new Dictionary<string, SerialPort>();
调试工具推荐
- 串口调试助手 监控原始数据流 发送测试指令
- 协议分析工具 解析数据帧结构 验证校验位
- 虚拟串口 使用com0com创建虚拟端口 模拟电子秤响应