模拟三菱FX2N系列PLC的串口通信(实测通过)
2014-12-29 10:18
295 查看
软件开发背景:由于项目需要,上位机软件与三菱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 = "关闭串口";
}
}
}
}
/*
功能:模拟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 = "关闭串口";
}
}
}
}
相关文章推荐
- 通过迈思德物联网网关将三菱Q00UJ系列PLC数据上传到云服务器
- 与三菱Q系列PLC-TCP通信(MC协议)学习总结
- 三菱Q系列PLC的modbusTCP通讯
- 三菱A系列PLC
- 三菱Q系列PLC的io分配
- PC和三菱FX系列PLC直接通过现成库和编程口进行 串口通讯
- labview通过hostlink读写Omron CJ系列PLC,同时与多把扫码枪进行通信(心得)
- C#PC与三菱Q系列PLC通信小实验中遇到的问题
- 三菱Q系列PLC的智能功能模块程序
- 紫金桥与三菱FX2N系列PLC编程口通讯
- 三菱Q系列PLC基本指令讲解
- Lotuser进阶系列(转)——DXL之通过程序修改Domino的设计
- MSDN Visual系列:WSSv3中通过Tokens使自定义应用页面得到ListId和ItemId
- 不通过注册表获取运营商,系列号等信息(ExTAPI)
- 通过Cisco MDS 9000系列多层交换机扩展SAN
- 王甲佳全息营销系列01-期望对试图通过网络实现或者兑现更多价值的人士有帮助
- 通过Win API 模拟鼠标点击,使C# Java交互 (PART.1 C#部分)
- 个人收藏Lotuser进阶系列(转)——通过 Lotus Domino Java 代理消费 Web 服务
- S7-200系列PLC与监控计算机通信实现的研究
- 通过 composition模拟 "has-a"或 "is-implemented-in-terms-of"