1 Star 0 Fork 1

lhx/serialtool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
FormSerialTool.cs 9.64 KB
一键复制 编辑 原始数据 按行查看 历史
// @brief
// @file FormSerialTool.cs
// @date 2022-03-08
// Copyright (C) 2022 doublecat
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using SerialTools.Properties;
using static System.Enum;
namespace SerialTools {
public partial class FrmSerial : Form {
private byte[] _buffer;
private string _logPath = string.Empty;
private StreamWriter _logWriter;
private int _recvCount;
private Thread _recvThread;
private bool _running;
private int _sendCount;
public FrmSerial() {
InitializeComponent();
}
private void frmSerial_Load(object sender, EventArgs e) {
string[] vs = SerialPort.GetPortNames();
cboPorts.Items.AddRange(vs);
if (string.IsNullOrEmpty(Settings.Default.Port) || vs.All(p => p != Settings.Default.Port))
cboPorts.SelectedIndex = 0;
else
cboPorts.SelectedItem = Settings.Default.Port;
txtBaud.Text = Settings.Default.Baud.ToString();
cboParity.Items.AddRange(GetNames(typeof(Parity)));
cboParity.SelectedItem = Settings.Default.Parity.ToString();
numDataBits.Value = Settings.Default.DataBits;
cboStopBits.Items.AddRange(GetNames(typeof(StopBits)));
cboStopBits.SelectedItem = Settings.Default.StopBits.ToString();
_buffer = new byte[Settings.Default.RecvBufferSize];
// 超时时间
serialPort.WriteTimeout = serialPort.ReadTimeout = Settings.Default.Timeout;
// Log文件名
saveFileDialog.FileName = Settings.Default.LogFileName;
lRecvFilePath.Text = Settings.Default.LogFileName;
if (!string.IsNullOrEmpty(Settings.Default.LogFileName)) {
_logWriter = new StreamWriter(saveFileDialog.FileName);
}
}
private void btnStart_Click(object sender, EventArgs e) {
if (!serialPort.IsOpen) {
serialPort.PortName = cboPorts.SelectedItem.ToString();
serialPort.BaudRate = int.Parse(txtBaud.Text);
serialPort.Parity = (Parity) Parse(typeof(Parity), (string) cboParity.SelectedItem);
serialPort.DataBits = (int) numDataBits.Value;
serialPort.StopBits = (StopBits) Parse(typeof(StopBits), (string) cboStopBits.SelectedItem);
serialPort.Open();
lInfo.Text = $"打开端口{serialPort.PortName}";
ParamtersSettingsEnable(false);
// 开始运行
_recvThread = new Thread(RecvThreadStart);
_recvThread.Name = "RecvThread";
_recvThread.Start();
} else {
lInfo.Text = "端口已经打开!";
}
}
private void RecvThreadStart() {
int rv = 0;
string s;
_running = true;
while (_running) {
// 检查接收缓冲区是否有数据
if (serialPort.BytesToRead > 0) {
rv = serialPort.Read(_buffer, 0, _buffer.Length);
_recvCount += rv;
s = Encoding.ASCII.GetString(_buffer, 0, rv);
// 当清除接收信息后,可能会卡在此处;
// 需要将Invoke()改为BeginInvoke()
txtRecv.BeginInvoke((Action<string>) (rs => {
txtRecv.AppendText(rs);
lRecv.Text = $"接收:{_recvCount.ToString()}";
}), s);
// 保存数据到文件
if (_logWriter != null) {
_logWriter.Write(s);
_logWriter.Flush();
}
}
// 需要释放一下cpu,以便刷新UI,否则可能会造成UI无反应;使用Thread.Yeild()也会出现UI冻结的情况!!!
Thread.Sleep(100);
}
}
private void ParamtersSettingsEnable(bool v) {
if (v) {
btnStart.Enabled = true;
cboPorts.Enabled = true;
txtBaud.Enabled = true;
numDataBits.Enabled = true;
cboStopBits.Enabled = true;
cboParity.Enabled = true;
} else {
btnStart.Enabled = false;
cboPorts.Enabled = false;
txtBaud.Enabled = false;
numDataBits.Enabled = false;
cboStopBits.Enabled = false;
cboParity.Enabled = false;
}
}
private void btnStop_Click(object sender, EventArgs e) {
if (serialPort.IsOpen) {
// 停止后台接收线程
_running = false;
// 此处可能会和线程中的异常处理代码冲突;
while (_recvThread.IsAlive) Thread.Yield();
serialPort.Close();
lInfo.Text = $"关闭端口{serialPort.PortName}";
ParamtersSettingsEnable(true);
}
}
private void txtSend_KeyDown(object sender, KeyEventArgs e) {
if (e.Control) {
e.SuppressKeyPress = true;
if (e.KeyCode == Keys.Enter)
if (serialPort.IsOpen) {
var bytes = Encoding.Default.GetBytes(txtSend.Text.ToCharArray());
serialPort.Write(bytes, 0, bytes.Length);
_sendCount += bytes.Length;
lSend.Text = $"发送:{_sendCount}";
} else {
lErr.Text = "端口未打开!";
}
}
}
private void frmSerial_FormClosing(object sender, FormClosingEventArgs e) {
if (serialPort.IsOpen) {
_running = false;
while (_recvThread.IsAlive) ;
serialPort.Close();
}
// 关闭log
_logWriter.Close();
// 保存配置
Settings.Default.Port = serialPort.PortName;
Settings.Default.Parity = serialPort.Parity;
Settings.Default.Baud = serialPort.BaudRate;
Settings.Default.DataBits = serialPort.DataBits;
Settings.Default.StopBits = serialPort.StopBits;
Settings.Default.LogFileName = saveFileDialog.FileName;
Settings.Default.Save();
}
private void ClearToolStripMenuItem_Click(object sender, EventArgs e) {
var txt = (TextBox) mnuMessage.Tag;
txt.Clear();
if (txt.Name == "txtRecv") {
_recvCount = 0;
} else if (txt.Name == "txtSend") {
_sendCount = 0;
}
}
private void txtRecv_MouseEnter(object sender, EventArgs e) {
mnuMessage.Tag = txtRecv;
}
private void txtSend_MouseEnter(object sender, EventArgs e) {
mnuMessage.Tag = txtSend;
}
private void btnRecvDataSave_Click(object sender, EventArgs e) {
saveFileDialog.InitialDirectory = Application.StartupPath;
if (saveFileDialog.ShowDialog() == DialogResult.OK) {
_logPath = saveFileDialog.FileName;
lRecvFilePath.Text = $"接收数据保存在:{saveFileDialog.FileName}";
// 打开log文件
if (_logWriter == null) {
_logWriter = new StreamWriter(saveFileDialog.FileName, true);
}
}
}
private void lRecvFilePath_Click(object sender, EventArgs e) {
// 如果保存的文件路径为空则退出
if (string.IsNullOrEmpty(saveFileDialog.FileName))
return;
ProcessStartInfo psi = new ProcessStartInfo(Settings.Default.Editor);
psi.Arguments = saveFileDialog.FileName;
psi.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(psi);
}
private void btnClearLog_Click(object sender, EventArgs e) {
bool running = false;
// 关闭接收
if ((_recvThread != null) && (_recvThread.IsAlive)) {
running = true;
_running = false;
while (_recvThread.IsAlive) {
}
}
if (!string.IsNullOrEmpty(saveFileDialog.FileName)) {
_logWriter.Close();
FileStream fs = File.Create(saveFileDialog.FileName);
fs.Close();
_logWriter = new StreamWriter(saveFileDialog.FileName);
}
if (running) {
_recvThread = new Thread(RecvThreadStart);
_recvThread.Name = "RecvThread";
_recvThread.Start();
}
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/lhx999/serialtool.git
git@gitee.com:lhx999/serialtool.git
lhx999
serialtool
serialtool
master

搜索帮助

D67c1975 1850385 1daf7b77 1850385