刚刚从头开始学习c#,在查询资料过程中,感觉各位大神写的太高深了,这里是我写的一个串口程序,希望与同我一样的小白们一同努力,不要放弃,向更深一步加油吧;
程序要求:与两个串口进行通讯,定时发出数据,对返回的数据进行处理(帧头帧尾识别),经过算法,得到一组数据,并将其输出到chart图表上(折线图),最后保存图表。
以下为代码:
using System;
using System.IO.Ports;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Timers;
using System.Windows.Forms.DataVisualization.Charting;
using System.IO.Ports;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Timers;
using System.Windows.Forms.DataVisualization.Charting;
namespace 接收完整版
{
public partial class Form1 : Form
{
private SerialPort sp1 = new SerialPort(); //建立串口sp1
private SerialPort sp2 = new SerialPort(); //建立串口sp2
public static double shuchu1; //sp1输出数据
public static double shuchu2; //sp2输出数据
public static double max0 = 0; //项目算法中参数
public static double c; //同上
public static double d; //同上
public static double d; //同上
public static int cishu=0; //定时器运行次数
static System.Timers.Timer t; //定时器声明
Series series = new Series("Spline"); //chart图标
public Form1()
{
InitializeComponent();
}
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
sp1.ReceivedBytesThreshold = 1; //sp1参数设置,这里是接收1个数据便促发接收处理程序;接下来是串口号,波特率,奇偶位,停止位,数据位数设置;
sp1.PortName = "COM5";
sp1.BaudRate = 115200;
sp1.Parity = Parity.None;
sp1.StopBits = StopBits.One;
sp1.DataBits = 8;
sp1.Open(); //sp1串口打开
sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived); //sp1接收数据事件
{
sp1.ReceivedBytesThreshold = 1; //sp1参数设置,这里是接收1个数据便促发接收处理程序;接下来是串口号,波特率,奇偶位,停止位,数据位数设置;
sp1.PortName = "COM5";
sp1.BaudRate = 115200;
sp1.Parity = Parity.None;
sp1.StopBits = StopBits.One;
sp1.DataBits = 8;
sp1.Open(); //sp1串口打开
sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived); //sp1接收数据事件
sp2.ReceivedBytesThreshold = 1; //sp2参数设置
sp2.PortName = "COM6";
sp2.BaudRate = 115200;
sp2.Parity = Parity.None;
sp2.StopBits = StopBits.One;
sp2.DataBits = 8;
sp2.Open();//打开串口
sp2.DataReceived += new SerialDataReceivedEventHandler(sp2_DataReceived);
Control.CheckForIllegalCrossThreadCalls = false; 线程间检测关闭(即跨线程调用不报错)
chart1.Series.Clear();
series.ChartType = SeriesChartType.Spline; //图类型Spline
chart1.Series.Add(series); //添加一个图表序列
this.chart1.ChartAreas[0].AxisY.Minimum = 0; //设置设置纵坐标的最小值0
this.chart1.ChartAreas[0].AxisY.Maximum = 0.2; //设置设置纵坐标的最大值0.2
this.chart1.ChartAreas[0].AxisX.Minimum = 0; //设置设置纵坐标的最小值0
this.chart1.ChartAreas[0].AxisX.Maximum = 2000; //设置设置纵坐标的最大值0.2
this.chart1.ChartAreas[0].AxisX.Interval = 100; //设置横坐标间隔为50,使得每个刻度间均匀分开的
this.chart1.ChartAreas[0].AxisY.Interval = 0.01;
this.chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Green; //背景网格线颜色为银色
this.chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Green; //背景网格线颜色为银色
this.chart1.ChartAreas[0].AxisX.Title = "次数/次"; //设置下方横坐标名称
this.chart1.ChartAreas[0].AxisY.Title = "同轴度/mm"; //设置左边纵坐标的名称
chart1.ChartAreas[0].Area3DStyle.Enable3D = true; //以3D形式展示
chart1.Series[0].Color = Color.Red; //线条颜色
}
private List<byte> buffer = new List<byte>(1048576); //sp1接收事件
void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
(
void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
(
int n = sp1.BytesToRead;//待读字节个数
byte[] buf = new byte[n];//创建n个字节的缓存
byte[] ReceiveBytes = new byte[9];
sp1.Read(buf, 0, n);//读到在数据存储到buf
byte[] buf = new byte[n];//创建n个字节的缓存
byte[] ReceiveBytes = new byte[9];
sp1.Read(buf, 0, n);//读到在数据存储到buf
//缓存数据
buffer.AddRange(buf);//不断地将接收到的数据加入到buffer链表中
buffer.AddRange(buf);//不断地将接收到的数据加入到buffer链表中
while (buffer.Count >= 6) //至少包含帧头(1字节)、数据(3字节)、帧尾(1字节)、效验位(1字节);
{
{
if (buffer[0] == 0x02) //到帧头 02H
{
{
if (buffer.Count < 6) //数据区尚未接收完整,
{
break;//跳出接收函数后之后继续接收数据
}
//得到完整的数据,复制到ReceiveBytes中进行校验
buffer.CopyTo(0, ReceiveBytes, 0, 6);//复制数据
byte check; //开始校验
check = 0x03;//帧尾
{
break;//跳出接收函数后之后继续接收数据
}
//得到完整的数据,复制到ReceiveBytes中进行校验
buffer.CopyTo(0, ReceiveBytes, 0, 6);//复制数据
byte check; //开始校验
check = 0x03;//帧尾
if (check != ReceiveBytes[4]) //帧尾验证位失败
{
buffer.RemoveRange(0, 6);//从链表中移除接收到的校验失败的数据,
{
buffer.RemoveRange(0, 6);//从链表中移除接收到的校验失败的数据,
continue; //继续执行while循环程序,
}
}
buffer.RemoveRange(0, 6);
string strRcv = null;
for (int i = 1; i < 4; i++) //窗体显示
{
strRcv += ReceiveBytes[i].ToString("X2"); //16进制显示
}
for (int i = 1; i < 4; i++) //窗体显示
{
strRcv += ReceiveBytes[i].ToString("X2"); //16进制显示
}
//
项目算法
//
}
else //帧头不正确时,清除
{
buffer.RemoveAt(0);//清除第一个字节,继续检测下一个。
}
else //帧头不正确时,清除
{
buffer.RemoveAt(0);//清除第一个字节,继续检测下一个。
}
}
}
private List<byte> buffer2 = new List<byte>(1048576); //sp2接收事件
void sp2_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int n = sp2.BytesToRead;//待读字节个数
byte[] buf2 = new byte[n];//创建n个字节的缓存
byte[] ReceiveBytes2 = new byte[11];
sp2.Read(buf2, 0, n);//读到在数据存储到buf
void sp2_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int n = sp2.BytesToRead;//待读字节个数
byte[] buf2 = new byte[n];//创建n个字节的缓存
byte[] ReceiveBytes2 = new byte[11];
sp2.Read(buf2, 0, n);//读到在数据存储到buf
//缓存数据
buffer2.AddRange(buf2);//不断地将接收到的数据加入到buffer链表中
buffer2.AddRange(buf2);//不断地将接收到的数据加入到buffer链表中
while (buffer2.Count >= 9) //至少包含帧头(1字节)、数据(7字节)、帧尾(1字节);
{
{
if (buffer2[0] == 0x02) //到帧头 02H
{
{
if (buffer2.Count < 9) //数据区尚未接收完整,
{
break;//跳出接收函数后之后继续接收数据
}
//得到完整的数据,复制到ReceiveBytes中进行校验
buffer2.CopyTo(0, ReceiveBytes2, 0, 9);//
byte check2; //开始校验
check2 = 0x03;
{
break;//跳出接收函数后之后继续接收数据
}
//得到完整的数据,复制到ReceiveBytes中进行校验
buffer2.CopyTo(0, ReceiveBytes2, 0, 9);//
byte check2; //开始校验
check2 = 0x03;
if (check2 != ReceiveBytes2[8]) //帧尾验证位失败
{
buffer2.RemoveRange(0, 9);//从链表中移除接收到的校验失败的数据,
{
buffer2.RemoveRange(0, 9);//从链表中移除接收到的校验失败的数据,
continue; //继续执行while循环程序,
}
}
buffer2.RemoveRange(0, 9);
char[] c = new char[9];
int a;
int a;
for (int i = 1, j = 0; i < 8; i++, j++)
{
a = Convert.ToInt32(ReceiveBytes2[i]);
c[j] = Convert.ToChar(a);
}
string b = new string(c);
txb2.Text = b;
shuchu2 = float.Parse(b);
{
a = Convert.ToInt32(ReceiveBytes2[i]);
c[j] = Convert.ToChar(a);
}
string b = new string(c);
txb2.Text = b;
shuchu2 = float.Parse(b);
}
else //帧头不正确,清除
{
buffer2.RemoveAt(0); //清除第一个字节,继续检测下一个。
}
else //帧头不正确,清除
{
buffer2.RemoveAt(0); //清除第一个字节,继续检测下一个。
}
}
}
private void button1_Click(object sender, EventArgs e) //点击开始按钮触发时间;这里需要取初值;
{
System.Timers.Timer t0 = new System.Timers.Timer(50); //实例化Timer类,设置间隔时间为50毫秒;
t0.Elapsed += new System.Timers.ElapsedEventHandler(theout0); //到达时间的时候执行事件;
t0.AutoReset = false; //设置是执行一次(false)还是一直执行(true);
t0.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;
}
{
System.Timers.Timer t0 = new System.Timers.Timer(50); //实例化Timer类,设置间隔时间为50毫秒;
t0.Elapsed += new System.Timers.ElapsedEventHandler(theout0); //到达时间的时候执行事件;
t0.AutoReset = false; //设置是执行一次(false)还是一直执行(true);
t0.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;
}
public void theout0(object source, System.Timers.ElapsedEventArgs e) //到达时间的时候执行事件;
{
string strFrame = "024D3F0371"; //sp1 发送单次读取指令;
string strFrame = "024D3F0371"; //sp1 发送单次读取指令;
byte[] hFrame = new byte[strFrame.Length / 2];
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16); //数据格式转换
}
sp1.Write(hFrame, 0, 5);
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16); //数据格式转换
}
sp1.Write(hFrame, 0, 5);
string strFrame2 = "024D454153555245204103"; //sp2 发送单次读取指令;
byte[] hFrame2 = new byte[strFrame2.Length / 2];
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11);
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11);
t = new System.Timers.Timer(20); //实例化Timer类,设置间隔时间为20毫秒;
t.Elapsed += new System.Timers.ElapsedEventHandler(theout); //到达时间的时候执行事件;
t.AutoReset = true; //设置是执行一次(false)还是一直执行(true);
t.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;
t.Elapsed += new System.Timers.ElapsedEventHandler(theout); //到达时间的时候执行事件;
t.AutoReset = true; //设置是执行一次(false)还是一直执行(true);
t.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;
}
public void theout(object source, System.Timers.ElapsedEventArgs e) //到达时间的时候执行事件;
{
cishu = cishu + 1;
string strFrame = "024D3F0371"; //sp1 发送单次读取指令;
byte[] hFrame = new byte[strFrame.Length / 2];
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16);
}
sp1.Write(hFrame, 0, 5);
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16);
}
sp1.Write(hFrame, 0, 5);
string strFrame2 = "024D454153555245204103"; //sp2 发送单次读取指令;
byte[] hFrame2 = new byte[strFrame2.Length / 2];
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11);
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11);
double max; //项目需要的算法,不用管它
max = System.Math.Abs((shuchu1 - c) + (shuchu2 - d));
txb32.Text = max.ToString("0.0000") ;
txb32.Text = max.ToString("0.0000") ;
if (shuchu1 != 0)
{
if(shuchu2 !=0)
{
if (max > max0)
{
max0 = max;
};
{
if(shuchu2 !=0)
{
if (max > max0)
{
max0 = max;
};
txb6.Text = max0.ToString("0.000");
txb31.Text = cishu.ToString("0");
series.Points.AddXY(cishu, max); //生成图表,因为实时生成会卡,所以这里接收完数据后,一起生成
}
}
}
}
private void button2_Click(object sender, EventArgs e) //暂停键
{
t.Stop();
chart1.Series[0].Points.Clear();
Application.Exit();
}
{
t.Stop();
chart1.Series[0].Points.Clear();
Application.Exit();
}
private void button3_Click(object sender, EventArgs e) //停止键
{
t.Stop();
sp1.Close();
sp2.Close();
}
{
t.Stop();
sp1.Close();
sp2.Close();
}
private void button4_Click(object sender, EventArgs e) //待测品放置完成后,读取初值
{
{
string strFrame = "024D3F0371"; //sp1 发送单次读取指令;
byte[] hFrame = new byte[strFrame.Length / 2];
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16);
}
sp1.Write(hFrame, 0, 5);
for (int i = 0; i < strFrame.Length / 2; i++)
{
hFrame[i] = Convert.ToByte(strFrame.Substring(i * 2, 2), 16);
}
sp1.Write(hFrame, 0, 5);
string strFrame2 = "024D454153555245204103"; //sp2 发送单次读取指令;
byte[] hFrame2 = new byte[strFrame2.Length / 2];
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11);
for (int i = 0; i < strFrame2.Length / 2; i++)
{
hFrame2[i] = Convert.ToByte(strFrame2.Substring(i * 2, 2), 16);
}
sp2.Write(hFrame2, 0, 11);
//
项目中输出显示到textbox
//
}
private void button5_Click(object sender, EventArgs e) //重置即停止并清楚现有数据
{
{
t.Stop();
chart1.Series[0].Points.Clear();
sp1.Close();
sp2.Close();
sp1.Open();
sp2.Open();
chart1.Series[0].Points.Clear();
sp1.Close();
sp2.Close();
sp1.Open();
sp2.Open();
max0 = 0;
txb6.Text = max0.ToString("0.000");
cishu = 0;
txb31.Text = cishu.ToString("0");
}
txb6.Text = max0.ToString("0.000");
cishu = 0;
txb31.Text = cishu.ToString("0");
}
private void btn6_Click(object sender, EventArgs e) //保存图像至C:/Users/Administrator/Desktop/同轴度
{
DateTime d = DateTime.Now; //读取当前时间,作为图像保存名称
string fileName = d.ToString("yyyyMMddHHmmss"); //将时间转为字符串,并去掉空格,冒号等
string GR_Path = @"C:/Users/Administrator/Desktop/同轴度/同轴度图像";
string fullFileName = GR_Path + "\\" + fileName + ".jpeg";
chart1.SaveImage(fullFileName, ChartImageFormat.Jpeg);
chart1.SaveImage("C:/Users/Administrator/Desktop/同轴度/同轴度图像.jpeg", ChartImageFormat.Jpeg);
{
DateTime d = DateTime.Now; //读取当前时间,作为图像保存名称
string fileName = d.ToString("yyyyMMddHHmmss"); //将时间转为字符串,并去掉空格,冒号等
string GR_Path = @"C:/Users/Administrator/Desktop/同轴度/同轴度图像";
string fullFileName = GR_Path + "\\" + fileName + ".jpeg";
chart1.SaveImage(fullFileName, ChartImageFormat.Jpeg);
chart1.SaveImage("C:/Users/Administrator/Desktop/同轴度/同轴度图像.jpeg", ChartImageFormat.Jpeg);
//保存图像路径:桌面/同轴度/同轴度图像.jpeg
}
}
}
}
}
}
源代码地址:https://download.csdn.net/download/yunsongblue/10277693