111,092
社区成员




using System;
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.IO.Ports;
using PortsThirdTry.usefulFun;
using System.Threading;
namespace PortsThirdTry
{
public partial class Form1 : Form
{
//全局预处理:创建实例,定义变量
PortsThirdTry.usefulFun.ClassCrc16 classCrc16 = new PortsThirdTry.usefulFun.ClassCrc16();
LittleFun littleFun = new LittleFun();
SerialPort comm = new SerialPort();
byte crcHi = 0x00;//crc高位
byte crcLo = 0x00;//crc低位
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//初始化下拉框参数
string[] ports = SerialPort.GetPortNames();
Array.Sort(ports); //冒泡程序对串口进行排序
comboPortName.Items.AddRange(ports);
comboPortName.SelectedIndex = comboPortName.Items.Count > 0 ? 0 : -1; //默认串口
comboBaudRate.SelectedIndex = comboBaudRate.Items.IndexOf("115200"); //默认波特率
comboDataBits.SelectedIndex = comboDataBits.Items.IndexOf("8");//默认数据位数
comboStopBits.SelectedIndex = comboStopBits.Items.IndexOf("1");//默认停止位数
comboParityBits.SelectedIndex = comboParityBits.Items.IndexOf("无");//默认校验方式
comm.ReadTimeout = 2000;//超时时间,2s
comm.DataReceived += choice;
}
#region 串口打开按钮
private void btnOpenPort_Click(object sender, EventArgs e)
{
//根据当前串口对象,来判断操作
if (comm.IsOpen)
{
comm.Close(); //打开时点击,则关闭串口
}
else//关闭时点击,则设置好端口,波特率后打开
{
comm.PortName = comboPortName.Text;
comm.BaudRate = int.Parse(comboBaudRate.Text);
comm.DataBits = int.Parse(comboDataBits.Text);
switch (comboStopBits.Text)//设置停止位数
{
case "1":
comm.StopBits = StopBits.One;
break;
case "1.5":
comm.StopBits = StopBits.OnePointFive;
break;
case "2":
comm.StopBits = StopBits.Two;
break;
case "无":
comm.StopBits = StopBits.None;
break;
default:
break;
}
switch (comboParityBits.Text)
{
case "无":
comm.Parity = Parity.None;
break;
case "奇校验":
comm.Parity = Parity.Odd;
break;
case "偶校验":
comm.Parity = Parity.Even;
break;
default:
break;
}
try
{
comm.Open();
}
catch (Exception)
{
//捕获到异常信息,创建一个新的comm对象,之前的不能用了。
comm = new SerialPort();
//现实异常信息给客户。
MessageBox.Show("该串口被占用,请更换其他串口");
}
}
//设置按钮的状态
btnOpenPort.Text = comm.IsOpen ? "关闭串口" : "打开串口";
if (btnOpenPort.Text == "关闭串口")
{
comboPortName.Enabled = false;
comboBaudRate.Enabled = false;
comboDataBits.Enabled = false;
comboStopBits.Enabled = false;
comboParityBits.Enabled = false;
}
else
{
comboPortName.Enabled = true;
comboBaudRate.Enabled = true;
comboDataBits.Enabled = true;
comboStopBits.Enabled = true;
comboParityBits.Enabled = true;
}
}
#endregion
#region 主机查询命令
# region 设置扫描步长
#region 开始扫描指令
#region 读取波长数据
int[] allWave = new int[30];//定义一个数组来存储波长数据
private void btnGetWaveLength_Click(object sender, EventArgs e)
{
Byte ScanLength = Convert.ToByte(comboGetChannels.Text);
byte[] sendGetWaveLengthData = new byte[4] { 0x10, 0x01, 0x06, ScanLength };//将要发送的数据组
byte[] sendGetWaveLengthCrc = classCrc16.Crc16(sendGetWaveLengthData, out crcHi, out crcLo);//将要发送的crc
byte[] sendGetWaveLength = new byte[sendGetWaveLengthData.Length + sendGetWaveLengthCrc.Length];//将要发送的完整数组
sendGetWaveLengthData.CopyTo(sendGetWaveLength, 0);
sendGetWaveLengthCrc.CopyTo(sendGetWaveLength, sendGetWaveLengthData.Length);
comm.Write(sendGetWaveLength, 0, sendGetWaveLength.Length);//发送扫描数据
//comm.DataReceived += comm_GetWaveLength;
//comm.ReceivedBytesThreshold = 126;//设置接收的缓冲字节数
}
void comm_GetWaveLength(List<byte> a)//
{
byte[] receiveGetWaveLength = (byte[]) a.ToArray();
int n = receiveGetWaveLength.Length;//comm.Read(receiveGetWaveLength, 0, n);
while (n < 126)
{
Thread.Sleep(50);
}
byte[] receiveGetWaveLengthData = new byte[n-2];//将收到的数据中的crc以外的部分去掉,用于校验对比
byte[] receiveGetWaveLengthCrc = new byte[2];
Array.Copy(receiveGetWaveLength, 0, receiveGetWaveLengthData, 0, n-2);
Array.Copy(receiveGetWaveLength, n-2, receiveGetWaveLengthCrc, 0, 2);
byte[] receiveGetWaveLengthCrc2 = classCrc16.Crc16(receiveGetWaveLengthData, out crcHi, out crcLo);
this.Invoke((EventHandler)(delegate //用invoke更新界面
{
if (!littleFun.equalOrNot(receiveGetWaveLengthCrc2, receiveGetWaveLengthCrc))
{
MessageBox.Show("扫描波长数据错误,请重新设置");
}
else
{
//写一个循环程序迭代光栅编号
for (int j = 3; j < 126; j++)
{
txtDataMessage.Text = "波长数据为:" + " ";
if ((j - 4) % 4 == 0)
{
int text = ((int)receiveGetWaveLength[j + 1] * 65536 + (int)receiveGetWaveLength[j + 2] * 256 + (int)receiveGetWaveLength[j + 3]) / 10000;
int x = (j - 4) / 4;
allWave[x] = text;
txtDataMessage.Text += allWave[x];
}
else
{
}
}
}
}));
}
#endregion
#region 峰值功率数据
#region 读取AD数据
#region 查询当前阈值
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
#region 手动设定阈值
void choice(object sender, SerialDataReceivedEventArgs e)
{
int n = comm.BytesToRead;
byte[] receiveData = new byte[n];
comm.Read(receiveData, 0, n);
int Data = receiveData[1];
List<byte> sendData = new List<byte>();
foreach (byte i in receiveData)
{
sendData.Add(i);
}
switch (Data)
{
case 3:
comm_receiveMachineSearchFun(sendData);
break;
case 4:
comm_ScanLengthFun(sendData);
break;
case 32:
comm_receiveBeginScanFun(sendData);
break;
case 1://表示需要执行读波长函数
comm_GetWaveLength(sendData);
break;
case 2:
comm_PeakRate(sendData);
break;
case 5:
break;
case 6:
if ((receiveData[6] & receiveData[4] & receiveData[5] & receiveData[7]) == 0)
{
comm_receiveGetThreshold(sendData);
}
else
{
comm_SetThreshold(sendData);
}
break;
}
}
}
}
while (n < 126)
{
Thread.Sleep(50);
}
这类代码,你就应该清理这类垃圾。重新理解和设计流程。
之所以“死循环+阻塞”,而且是给出了一个既不足够长也不足够短的数值——50,这个完全瞎猜的数值,之所以这样设计,就是因为这类通讯程序设计根本的理念就错误了。返回的数据经常达不到126个字节