C#上位机—事件传参
主窗口的操作
子窗口的操作
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;
namespace 串口助手
{
public partial class Form1 : Form
{
private bool isOpen = false;
private bool isRxShow = true;
private List<byte> reciveBuffer = new List<byte>();
private List<byte> sendBuffer = new List<byte>();
private int reciveCount = 0;
private int sendCount = 0;
private Queue<byte> bufferQueue = null;
private bool isHeadRecive = false;
private int frameLenth = 0;
public TransmitData transmitData;
public event TransmitEventHandler transmitData2;
//SerialPort
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
//在设计页面已经预先添加了COM1 COM2 COM3
//this.port_cbb.Items.Add("COM4");
//this.port_cbb.Items.Add("COM5");
//this.port_cbb.SelectedIndex = 2;
//this.baud_cbb.SelectedIndex = 1;
//this.check_cbb.SelectedIndex = 0;
//this.databit_cbb.SelectedIndex = 3;
//this.stopbit_cbb.SelectedIndex = 0;
// 给发送框添加预设文本
// this.send_rtb.Text = "我是发送框";
// 给接收框添加预设文本
// this.recive_rtb.Text = "我是接收框";
serialLoad();
// 实例化
bufferQueue = new Queue<byte>();
Form2 fr2 = new Form2();
// 接收数据委托窗体2 ReciveData 执行显示
//transmitData += fr2.ReciveData;
// 接收数据事件窗体2 ReciveData2 执行显示
transmitData2 += new TransmitEventHandler(fr2.ReciveData2);
// 窗体2发送委托窗体1 sendBytes 执行发送
// fr2.useForm1Send += sendBytes;
// 窗体2发送事件窗体1 sendbytes2 执行发送
fr2.useForm1Send2 += new TransmitEventHandler(sendbytes2);
fr2.Show();
}
private void sendbytes2(object sender, TransmitEventArgs e)
{
serialPort1.Write(e.data, 0, e.data.Length);
sendCount += e.data.Length;
sencount_tssl.Text = sendCount.ToString();
}
private void sendBytes(byte[] data)
{
serialPort1.Write(data, 0, data.Length);
sendCount += data.Length;
sencount_tssl.Text = sendCount.ToString();
}
private void serialLoad()
{
EncodingInfo[] encodingInfos = Encoding.GetEncodings();
RegistryKey keyCom = Registry.LocalMachine.OpenSubKey(@"Hardware\DeviceMap\SerialComm");
string[] sSubKeys = keyCom.GetValueNames();
port_cbb.Items.Clear();
foreach (var sValue in sSubKeys)
{
string portName = (string)keyCom.GetValue(sValue);
port_cbb.Items.Add(portName);
}
this.port_cbb.SelectedIndex = 0;
this.baud_cbb.SelectedIndex = 1;
this.check_cbb.SelectedIndex = 0;
this.databit_cbb.SelectedIndex = 3;
this.stopbit_cbb.SelectedIndex = 0;
}
private void sendData()
{
serialPort1.Write(sendBuffer.ToArray(),0,sendBuffer.Count);
sendCount += sendBuffer.Count;
sencount_tssl.Text = sendCount.ToString();
}
private void send_btn_Click(object sender, EventArgs e)
{
// 如果发送的数据不为空,则接收
if (this.send_rtb.Text != "" && serialPort1.IsOpen)
{
Console.WriteLine(Transform.ToHexString(sendBuffer.ToArray()));
sendData();
}
else
{
MessageBox.Show("请先输入发送数据!");
}
}
private void open_btn_Click(object sender, EventArgs e)
{
try
{
if (serialPort1.IsOpen == false)
{
serialPort1.PortName = port_cbb.Text;
serialPort1.BaudRate = Convert.ToInt32(baud_cbb.Text);
serialPort1.DataBits = Convert.ToInt32(databit_cbb.Text);
switch (check_cbb.SelectedIndex)
{
// none odd even
case 0:
serialPort1.Parity = Parity.None;
break;
case 1:
serialPort1.Parity = Parity.Odd;
break;
case 2:
serialPort1.Parity = Parity.Even;
break;
default:
serialPort1.Parity = Parity.None;
break;
}
switch (stopbit_cbb.SelectedIndex)
{
// 1 1.5 2
case 0:
serialPort1.StopBits = StopBits.One;
break;
case 1:
serialPort1.StopBits = StopBits.OnePointFive;
break;
case 2:
serialPort1.StopBits = StopBits.Two;
break;
default:
serialPort1.StopBits = StopBits.One;
break;
}
serialPort1.Open();
isOpen = true;
open_btn.Text = "关闭串口";
}
else
{
serialPort1.Close();
isOpen = false;
open_btn.Text = "打开串口";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString()+serialPort1.PortName.ToString());
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (isRxShow == false) return;
// 1,需要读取有效的数据 BytesToRead
byte[] dataTemp = new byte[serialPort1.BytesToRead];
serialPort1.Read(dataTemp,0,dataTemp.Length);
reciveBuffer.AddRange(dataTemp);
reciveCount += dataTemp.Length;
//?. = 如果transmitData !=null
// transmitData?.Invoke(dataTemp);
transmitData2?.Invoke(this, new TransmitEventArgs { data = dataTemp });
this.Invoke(new EventHandler(delegate
{
// 显示接收数据的长度
recivecount_tssl.Text = reciveCount.ToString();
if (startData_chb.Checked == false)
{
if (!recivehex_chb.Checked)
{
// 2, 编码格式的选择
string str = Encoding.GetEncoding("gb2312").GetString(dataTemp);
// 3,0x00 -> \0 结束 不会显示
str = str.Replace("\0", "\\0");
recive_rtb.AppendText(str);
// recive_rtb.AppendText(Encoding.GetEncoding("gb2312").GetString(dataTemp).Replace("\0", "\\0"));
}
else
{
// 十六进制是选中的状态下
recive_rtb.AppendText(Transform.ToHexString(dataTemp, " "));
}
}
else
{
// 解析数据 queue
foreach (byte item in dataTemp)
{
// 入列
bufferQueue.Enqueue(item);
}
// 解析获取帧头
if (isHeadRecive == false)
{
foreach (byte item in bufferQueue.ToArray())
{
if (item != 0x7f)
{
// 出列
bufferQueue.Dequeue();
Console.WriteLine("not 0x7f, Dequeue !!");
}
else
{
// get 0x7f from bufferQueue
isHeadRecive = true;
Console.WriteLine("0x7f is recived !!");
break;
}
}
}
if (isHeadRecive == true)
{
// 判断有数据帧长度
if (bufferQueue.Count >= 2)
{
Console.WriteLine(DateTime.Now.ToLongTimeString());
Console.WriteLine($"show the data in bufferQueue{Transform.ToHexString(bufferQueue.ToArray())}");
Console.WriteLine($"frame lenth ={String.Format("{0:X2}", bufferQueue.ToArray()[1])}");
frameLenth = bufferQueue.ToArray()[1];
// 一帧完整的数据长度判断,不代表数据是正确的
if(bufferQueue.Count>=1+1+frameLenth+2)
{
byte[] frameBuffer = new byte[1 + 1 + frameLenth + 2];
Array.Copy(bufferQueue.ToArray(), 0, frameBuffer, 0, frameBuffer.Length);
if(crc_chech(frameBuffer))
{
Console.WriteLine("frame is check ok,pick it");
data_txb.Text = Transform.ToHexString(frameBuffer);
data1_txb.Text = String.Format("{0:X2}", frameBuffer[2]);
data2_txb.Text = String.Format("{0:X2}", frameBuffer[3]);
data3_txb.Text = String.Format("{0:X2}", frameBuffer[4]);
data4_txb.Text = String.Format("{0:X2}", frameBuffer[5]);
}
else
{
// 无效数据
Console.WriteLine("bad frame, drop it");
}
for(int i=0; i<1 + 1+frameLenth+2;i++)
{
bufferQueue.Dequeue();
}
isHeadRecive = false;
}
}
//接续接收数据
}
}
}));
}
private bool crc_chech(byte[] frameBuffer)
{
/*大端模式: 是指数据的高字节保存在内存的低地址中,
* 而数据的低字节保存在内存的高地址中,这样的存储
* 模式有点儿类似于把数据当作字符串顺序处理:地址
* 由小向大增加,而数据从高位往低位放;这和我们的
* 阅读习惯一致。
*
* 小端模式: 是指数据的高字节保存在内存的高地址中,
* 而数据的低字节保存在内存的低地址中,这种存储模
* 式将地址的高低和数据位权有效地结合起来,高地址
* 部分权值高,低地址部分权值低。
*/
bool ret = false;
byte[] temp = new byte[frameBuffer.Length-2];
Array.Copy(frameBuffer, 0, temp, 0, temp.Length);
byte[] crcdata = DataCheck.DataCrc16_Ccitt(temp, DataCheck.BigOrLittle.BigEndian);
if (crcdata[0] == frameBuffer[frameBuffer.Length - 2] &&
crcdata[1]== frameBuffer[frameBuffer.Length-1])
{
// check ok
ret = true;
}
return ret;
}
private void stop_btn_Click(object sender, EventArgs e)
{
if (isRxShow == true)
{
isRxShow = false;
stop_btn.Text = "取消暂停";
}
else
{
isRxShow = true;
stop_btn.Text = "暂停";
}
}
private void recivehex_chb_CheckedChanged(object sender, EventArgs e)
{
if (recive_rtb.Text == "") return;
if (recivehex_chb.Checked)
{
recive_rtb.Text = Transform.ToHexString(reciveBuffer.ToArray()," ");
}
else
{
recive_rtb.Text = Encoding.GetEncoding("gb2312").GetString(reciveBuffer.ToArray()).Replace("\0","\\0");
}
}
private void clear_btn_Click(object sender, EventArgs e)
{
reciveBuffer.Clear();
reciveCount = 0;
recivecount_tssl.Text = "0";
recivecount_tssl.Text = "";
recive_rtb.Text = "";
}
private void autoclear_chb_CheckedChanged(object sender, EventArgs e)
{
if (autoclear_chb.Checked)
{
timer1.Start();
}
else
{
timer1.Stop();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (recive_rtb.Text.Length > 4096)
{
reciveBuffer.Clear();
recive_rtb.Text = "";
recivecount_tssl.Text = "";
}
}
private void send_rtb_Leave(object sender, EventArgs e)
{
if (sendhex_chb.CheckState == CheckState.Checked)
{
if (DataEncoding.IsHexString(send_rtb.Text.Replace(" ", "")))
{
sendBuffer.Clear();
sendBuffer.AddRange(Transform.ToBytes(send_rtb.Text.Replace(" ", "")));
}
else
{
MessageBox.Show("请输入正确的十六进制数据!!");
send_rtb.Select();
}
}
else
{
sendBuffer.Clear();
sendBuffer.AddRange(Encoding.GetEncoding("gb2312").GetBytes(send_rtb.Text));
}
}
private void send_rtb_TextChanged(object sender, EventArgs e)
{
// 十六进制切换 会出现问题 这问题就是0x00 转换
}
private void sendhex_chb_CheckedChanged(object sender, EventArgs e)
{
if (send_rtb.Text == "") return;
if (sendhex_chb.Checked == true)
{
send_rtb.Text = Transform.ToHexString(sendBuffer.ToArray(), " ");
}
else
{
send_rtb.Text = Encoding.GetEncoding("gb2312").GetString(sendBuffer.ToArray()).Replace("\0","\\0");
}
}
private void sendclear_btn_Click(object sender, EventArgs e)
{
sendBuffer.Clear();
send_rtb.Text = "";
sendCount = 0;
sencount_tssl.Text = "0";
}
}
}