功能实现

串口基础功能参考

编写相关

winform 中使用串口就需要在左侧工具箱里拖入一个serialPort,如下图所示

初始化串口

1
2
3
public SerialPort serialPort;
private bool Listening = false;//是否没有执行完invoke相关操作
private bool Closing = false;//是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#region 初始化串口
private void InitPort()
{
try
{
serialPort1.PortName = "COM1";
serialPort1.BaudRate = 4800;
serialPort1.DataBits = 8;
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.WriteTimeout = 3000;
serialPort1.ReadTimeout = 3000;
serialPort1.ReceivedBytesThreshold = 1;
serialPort1.DtrEnable = true;
serialPort1.RtsEnable = true;
updateText = new UpdateTextEventHandler(UpdateTextBox); //实例化委托对象
serialPort1.Handshake = Handshake.RequestToSend;
serialPort1.Open();
//MessageBox.Show("开始");
button3.Text = "关闭串口";
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion

串口获取数据

我解析这个吊钩秤是通过称一直向外发送数据,程序解析数据,通过截取字符串,获取两个空白之间的数据并显示在文本框上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#region  串口获取数据
public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (Closing) return;//如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环
try
{
Listening = true;//设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
Thread.Sleep(600);

string SDateTemp = "";
int len = serialPort1.BytesToRead;

Byte[] readBuffer = new Byte[len];
serialPort1.Read(readBuffer, 0, len);

SDateTemp = Encoding.Default.GetString(readBuffer);
//MessageBox.Show(SDateTemp);


int L = SDateTemp.IndexOf(" ");
int length = SDateTemp.Length;
string str1 = SDateTemp.Substring(L, length - L).Trim();

int L2 = str1.IndexOf(" ");
int length2 = str1.Length;
str2 = str1.Substring(0, L2).Trim();

if (!string.IsNullOrEmpty(str2))
{
this.BeginInvoke(new UpdateTextEventHandler(UpdateTextBox), new string[] { str2 });
//SDateTemp = GetValue(SDateTemp, "@G002", "kg").Trim(); //多少kg
}

//this.Invoke(new UpdateTextEventHandler(UpdateTextBox), new string[] { SDateTemp });

}
finally
{
Listening = false;//我用完了,ui可以关闭串口了。
}
}
#endregion

跟新文本框显示数据

1
2
3
4
5
6
7
private void UpdateTextBox(string text)
{
if (!string.IsNullOrEmpty(text))
{
textBox6.Text = text;
}
}

正则解析

如果串口发送的数据时规范的并且可以用正则解析的话,可以使用下边的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#region 获得字符串中开始和结束字符串之间的值
/// <summary>
/// 获得字符串中开始和结束字符串之间的值
/// </summary>
/// <param name="str">字符串</param>
/// <param name="A">开始</param>
/// <param name="B">结束</param>
/// <returns></returns>
public static string GetValue(string str, string A, string B)
{
Regex rg = new Regex("(?<=(" + A + "))[.\\s\\S]*?(?=(" + B + "))", RegexOptions.Multiline | RegexOptions.Singleline);
//Regex rg = new Regex("(?<=(" + A + "))[.\\d]*?(?=(" + B + "))", RegexOptions.Multiline | RegexOptions.Singleline);

return rg.Match(str).Value;
}
#endregion

注:如果采用了上边GetValue方法的话,在serialPort1_DataReceived 方法中,带注释的两行就需要取消注释使用。


相关链接

  1. c#(winform)通过串口读取并解析数据

=================我是分割线=================

欢迎到公众号来唠嗑: