软件开发背景:由于项目需要,上位机软件与三菱FX2N系列PLC的串口交换数据时,但手头上又没有PLC硬件,所以开发了这样一个工具来当PLC使用。
/*
功能:模拟PLC的数据通信
作者:
日期:2013-05-01
说明:
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace CommAssist
{
public partial class Form1 : Form
{
public delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[128];
Byte[] CommRcvBuf = new Byte[128];
int RcvCount = 0;
bool bFlagRcvOK=false;
bool RcvFlag = false;
SerialPort Comm = new SerialPort("com7", 19200, Parity.None, 8, StopBits.One);
public Displaydelegate disp_delegate;
public Form1()
{
disp_delegate = new Displaydelegate(DispUI);
InitializeComponent();
int mytemp;
comboBox1.SelectedItem = "com7";
Comm.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
string[] ports = SerialPort.GetPortNames();
Array.Sort(ports);
comboBox1.Items.AddRange(ports);
comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;
}
public void DispUI(byte[] InputBuf)
{
//textBox1.Text = Convert.ToString(InputBuf);
int i;
byte GetData;
for (i = 0; i < InputBuf[0]; i++)
{
if (!bFlagRcvOK)
{
GetData = InputBuf[1+i];
switch (RcvCount)
{
case 0: if (GetData == 0x05)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
case 1: if (GetData == 0x30)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else if (GetData == 0x05)
{
}
else
{
RcvCount = 0;
}
break;
case 2: if (GetData == 0x31)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
case 3: if (GetData == 0x46)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
case 4: if (GetData == 0x46)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
default:
RcvFlag = true;
break;
}
if (RcvFlag)
// receive valid data
{
RcvFlag = false;
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
if (RcvCount >= 17)
{
//MessageBox.Show("收到串口数据"); test
//BtnTest_Click();
this.BtnTest_Click(null,null);
bFlagRcvOK = false;
// 错误溢出处理
RcvCount = 0;
}
}
}
else
break;
}
ASCIIEncoding encoding = new ASCIIEncoding();
textBox1.Text= encoding.GetString(InputBuf);
//return (constructedString);
}
private void BtnTest_Click(object sender, EventArgs e) // 返回主机
{
int i;
string buf;
byte temp;
Byte[] sum = new Byte[10];
try
{
OutputBuf[0] = 0x02;
OutputBuf[1] = 0x30;
OutputBuf[2] = 0x31;
OutputBuf[3] = 0x46;
OutputBuf[4] = 0x46;
//-------------
OutputBuf[5] = 0x30;
OutputBuf[6] = 0x31;
OutputBuf[7] = 0x30;
OutputBuf[8] = 0x31;
OutputBuf[9] = 0x30;
OutputBuf[10] = 0x31;
OutputBuf[11] = 0x30;
OutputBuf[12] = 0x31;
OutputBuf[13] = 0x30;
OutputBuf[14] = 0x31;
OutputBuf[15] = 0x30;
OutputBuf[16] = 0x31;
OutputBuf[17] = 0x30;
OutputBuf[18] = 0x31;
OutputBuf[19] = 0x30;
OutputBuf[20] = 0x31;
OutputBuf[21] = 0x03;
sum[0] = 0;
for (i = 0; i < 21; i++)
sum[0] +=OutputBuf[i+1];
string str = BitConverter.ToString(sum);
OutputBuf[22] = (byte)str[0];
OutputBuf[23] = (byte)str[1];
Comm.Write(OutputBuf,0,24);
}
catch (TimeoutException ex) //异常处理
{
MessageBox.Show(ex.ToString());
}
}
void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int count,i;
Byte[] InputBuf = new Byte[128];
System.Threading.Thread.Sleep(20);
try
{
count = Comm.BytesToRead;
Comm.Read(InputBuf,0,Comm.BytesToRead);
for (i = 0; i < count; i++)
{
InputBuf[count - i] = InputBuf[count - i-1];
}
InputBuf[0] = (byte)count;
//InputBuf = UnicodeEncoding.Default.GetBytes(strRD);
//System.Threading.Thread.Sleep(50);
this.Invoke(disp_delegate, InputBuf);
}
catch (TimeoutException ex) //超时处理
{
MessageBox.Show(ex.ToString());
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) //选择串口的处理过程
{
bool b_OpenFlag = Comm.IsOpen;
if (b_OpenFlag == true)
{
Comm.Close();
Comm.PortName = comboBox1.SelectedItem.ToString();
Comm.Open();
}
else
{
Comm.PortName = comboBox1.SelectedItem.ToString();
}
}
private void OpenSerialPort_Click(object sender, EventArgs e) //点击“打开串口”按钮的操作
{
if (OpenSerialPort.Text == "关闭串口")
{
Comm.Close();
OpenSerialPort.Text = "打开串口";
}
else
{
Comm.Open();
OpenSerialPort.Text = "关闭串口";
}
}
}
}