📄 fmain.cs
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MySerial
{
public partial class FMain : Form
{
#region Constants
//字节位置定义
private const int POS_HEADER = 0; //同步头
private const int POS_CTRLBYTE = 6; //控制字
private const int POS_FRAMETYPE = 7; //帧类型
private const int POS_INFOBYTENUM = 8; //信息字数
private const int POS_SRC_STATION = 9; //源站
private const int POS_DST_STATION = 10;//目的站
private const int POS_CHECKSUM = 11;//校验码
private const int INFOBYTE_SIZE = 6;//信息字大小
#endregion Constants
private delegate void HandleInterfaceUpdateDelegate(byte[] RecvData,int iLen); //委托,此为重点
private HandleInterfaceUpdateDelegate interfaceUpdateHandle;
private byte[] PackageBuf = new byte[4096];
private int PackageBufLength = 0;
FDataShow pFDataShow;
public FMain()
{
InitializeComponent();
}
private void FMain_Load(object sender, EventArgs e)
{
interfaceUpdateHandle = new HandleInterfaceUpdateDelegate(OnRecvData); //实例化委托对象
pFDataShow = new FDataShow();
ShowInfo("A present from Alva.\r\n");
ShowInfo("hz_glq@126.com\r\n");
}
private void FMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (sp1.IsOpen)
{
sp1.Close();
}
}
private void mi_OpenPort_Click(object sender, EventArgs e)
{
string sComParam = "";
if (sp1.IsOpen)
{
sp1.Close();
stbTxt_Info1.Text = "串口已关闭";
mi_OpenPort.Text = "打开串口";
}
else
{
sp1.Open();
sComParam += sp1.PortName + ",";
sComParam += sp1.BaudRate.ToString() + ",";
sComParam += sp1.Parity.ToString() + ",";
sComParam += sp1.DataBits.ToString() + ",";
sComParam += sp1.StopBits.ToString();
stbTxt_Info1.Text = sComParam;
mi_OpenPort.Text = "关闭串口";
}
}
private void sp1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int recvLen = 0;
byte[] readBuffer = new byte[1024];
recvLen = sp1.Read(readBuffer, 0, 1024);
//this.Invoke(interfaceUpdateHandle, readBuffer,recvLen);
this.BeginInvoke(interfaceUpdateHandle, readBuffer,recvLen);
}
private void OnRecvData(byte[] RecvData, int iLen)
{
int i;
for (i = 0; i < iLen; i++)
{
if (PackageBufLength >= PackageBuf.Length)
ShowErrInfo("为防止缓存溢出而丢弃了" + Convert.ToString(iLen - i) + "字节数据");
else
PackageBuf[PackageBufLength++] = RecvData[i];
}
PackageAdjust();
}
private void mi_SendHellow_Click(object sender, EventArgs e)
{
sp1.WriteLine("Hellow Alva!\r\n");
}
private void mi_ComSet_Click(object sender, EventArgs e)
{
FComSet pFComSet = new FComSet();
if (pFComSet.ShowDialog() == DialogResult.OK)
{
rtb_Info.AppendText("Com Setup\r\n");
rtb_Info.AppendText(pFComSet.cbb_ComID.Text + " ");
rtb_Info.AppendText("BaudRate: " + pFComSet.cbb_BaudRate.Text + " ");
rtb_Info.AppendText("Parity: " + pFComSet.cbb_Parity.Text + " ");
rtb_Info.AppendText("DataBits: " + pFComSet.cbb_DataBits.Text + " ");
rtb_Info.AppendText("StopBits: " + pFComSet.cbb_StopBits.Text + "\r\n");
sp1.PortName = pFComSet.cbb_ComID.Text;
sp1.BaudRate = Convert.ToInt16(pFComSet.cbb_BaudRate.Text);
switch (pFComSet.cbb_Parity.SelectedIndex)
{
case 0:
sp1.Parity = System.IO.Ports.Parity.None;
break;
case 1:
sp1.Parity = System.IO.Ports.Parity.Odd;
break;
case 2:
sp1.Parity = System.IO.Ports.Parity.Even;
break;
case 3:
sp1.Parity = System.IO.Ports.Parity.Mark;
break;
case 4:
sp1.Parity = System.IO.Ports.Parity.Space;
break;
default:
sp1.Parity = System.IO.Ports.Parity.None;
break;
}
sp1.DataBits = Convert.ToInt16(pFComSet.cbb_DataBits.Text);
switch (pFComSet.cbb_StopBits.SelectedIndex)
{
case 0:
sp1.StopBits = System.IO.Ports.StopBits.One;
break;
case 1:
sp1.StopBits = System.IO.Ports.StopBits.OnePointFive;
break;
case 2:
sp1.StopBits = System.IO.Ports.StopBits.Two;
break;
default:
sp1.StopBits = System.IO.Ports.StopBits.One;
break;
}
}
}
private void PackageAdjust()
{
int iHead;
iHead = FindHeader();
if (iHead >= 0)
{
if (iHead > 0)
MovePackageBuf(iHead);
ParsePackageBuf();
}
}
private int FindHeader()
{
int i;
int headCount = 0;
for (i = 0; i < PackageBufLength ; i++)
{
if (PackageBuf[i] == 0xEB && headCount % 2 == 0)
headCount++;
else if (PackageBuf[i] == 0x90 && headCount % 2 != 0)
headCount++;
else
headCount = 0;
if (headCount == 6)
return i - 5;
}
return -1;
}
private void MovePackageBuf(int uiOffset)
{
int i;
int j=0;
for (i = uiOffset; i < PackageBufLength ; i++)
{
PackageBuf[j++] = PackageBuf[i];
}
PackageBufLength -= uiOffset;
}
private void ShowPacakgeBuf()
{
int i;
string sDebug = "";
rtb_Info.AppendText("\r\n*********************************************\r\n");
for (i = 0; i < PackageBufLength; i++)
{
sDebug += PackageBuf[i].ToString("X2");
if ((i + 1) % 6 == 0)
sDebug += " ";
}
rtb_Info.AppendText(sDebug);
rtb_Info.AppendText("\r\n*********************************************\r\n");
}
private void ShowInfo(string sInfo)
{
Color ColorBak = rtb_Info.SelectionColor;
SetTextColor(Color.Purple);
rtb_Info.AppendText(sInfo);
SetTextColor(ColorBak);
}
private void ShowErrInfo(string sInfo)
{
Color ColorBak = rtb_Info.SelectionColor;
SetTextColor(Color.Red);
rtb_Info.AppendText(sInfo);
SetTextColor(ColorBak);
}
private bool CheckCRC8(int Offset)
{
Int64 iSrc = 0x000000000000;
Int64 iGX = 0x838000000000;
Int64 iHBit = 0x800000000000;
Int64 iCRC;
int i;
for (i = 0; i < 5; i++)
{
iSrc = iSrc << 8;
iSrc = iSrc | PackageBuf[Offset + i];
}
iSrc = iSrc << 8;
for (i = 0; i < 40; i++)
{
if ((iSrc & iHBit)!=0)
iSrc = iSrc ^ iGX;
iGX = iGX >> 1;
iHBit = iHBit >> 1;
}
iSrc = (iSrc ^ 0xFF) & 0xFF;
iCRC = 0;
iCRC = iCRC | PackageBuf[Offset + 5];
if (iSrc == iCRC)
return true;
else
{
ShowErrInfo("CRC校验错误(002)!");
ShowInfoWord(Offset);
return false;
}
}
private void ParsePackageBuf()
{
if (PackageBufLength > 12)
{
if (!CheckCRC8(POS_CTRLBYTE))
{
ShowErrInfo("CRC校验错误(001)!");
ShowInfoWord(POS_CTRLBYTE);
MovePackageBuf(POS_CTRLBYTE);
}
}
else
return;
if (PackageBufLength < (PackageBuf[POS_INFOBYTENUM] * INFOBYTE_SIZE + 12))
return;
ShowPackage();
if ((PackageBuf[POS_CTRLBYTE] & 0x80) != 0)
{
ShowInfo("自定义帧 ");
}
else
{
if ( (PackageBuf[POS_CTRLBYTE] & 0x20) != 0)
ShowInfo("源站:" + PackageBuf[POS_SRC_STATION].ToString() + " ");
if ((PackageBuf[POS_CTRLBYTE] & 0x10) != 0)
ShowInfo("目的站:" + PackageBuf[POS_DST_STATION].ToString() + " ");
switch (PackageBuf[POS_FRAMETYPE])
{
case 0x61:
ShowInfo("重要遥测(A帧) ");
if ((PackageBuf[POS_CTRLBYTE] & 0x40) != 0)
ParseYCFrame();
break;
case 0xC2:
ShowInfo("次要遥测(B帧) ");
if ((PackageBuf[POS_CTRLBYTE] & 0x40) != 0)
ParseYCFrame();
break;
case 0xB3:
ShowInfo("一般遥测(C帧) ");
if ((PackageBuf[POS_CTRLBYTE] & 0x40) != 0)
ParseYCFrame();
break;
case 0xF4:
ShowInfo("遥信状态(D1帧) ");
if ((PackageBuf[POS_CTRLBYTE] & 0x40) != 0)
ParseYXFrame();
break;
case 0x85:
ShowInfo("电能脉冲数值(D2帧) ");
if ((PackageBuf[POS_CTRLBYTE] & 0x40) != 0)
ParseDNFrame();
break;
case 0x26:
ShowInfo("事件顺序记录(E帧) ");
if ((PackageBuf[POS_CTRLBYTE] & 0x40) != 0)
ParseSOEFrame();
break;
default :
ShowInfo("未知的帧类型: ");
break;
}
}
MovePackageBuf(POS_CTRLBYTE);
ShowInfo("\r\n\r\n");
}
private void ShowInfoWord(int iBaseAddr)
{
int i;
string sHexData = "";
Color ColorBak = rtb_Info.SelectionColor;
SetTextColor(Color.Red);
for (i = 0; i < 6; i++)
{
sHexData += PackageBuf[iBaseAddr + i].ToString("X2");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -