小弟正在学习C#中,不过近期要交一个作业,有关SerialPort的,也查了一些帖子,不过实在看不懂,还是把自己这个程序传上来求各位指点了。这里想要实现的是Modbus通信协议下的向串口收发数据,Modbus协议的子程序已经调试验证过了,没有问题,就是通过SerialPort收发数据的这个程序有问题,每次输入一组数据后,发送,就会出现类似死机现象,总之自己也觉得这个程序问题很大,还是请各位大虾指点啊,急需!!!namespace Strategy_Comm_02
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} /*********************************************初始化串口信息*********************************************************************/
private void initPortmessage(string baud, string databits, string portname)
{
serialPort.BaudRate = Convert.ToByte(baud);
serialPort.DataBits = Convert.ToByte(databits);
//serialPort.Parity = paritybox.Text;
//serialPort.StopBits = (int)(stopbitsbox.Text);
serialPort.PortName = portname;
} //*******************************************指令的标准输入为每个信息字符必须以两位的16进制数表示*******************************/
private byte[] stringto16int(string str)
{
char[] cstr = str.ToCharArray();
byte[] buf = new byte[1024];
string ss;
int j = 0;
for (int i = 0; i < cstr.Length; i=i+2) //**********指令的标准输入为每个信息字符必须以两位的16进制数表示,范围0——F;
{
ss = Convert.ToString(cstr[i]) + Convert.ToString(cstr[i+1]);
buf[j] = Convert.ToByte(ss);
j++;
} return buf;
}
/********************************************定时触发的发送/读取数据事件*********************************************************/
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] buffer1 = new byte[1024]; //=================根据通信协议规则生成的命令代码,将发送到缓冲区的内容
byte[] buffer2 = new byte[1024];
Modbus mmodbus = new Modbus(); byte[] command1 = new byte[1024]; //**********输入信号的命令
byte[] command2 = new byte[1024]; //**********响应信号的命令
command1 = stringto16int(readbox.Text);
switch (command1[1]) //================ 根据功能位function code 决定执行读/写操作
{
case 3: //=================function=0X03,即从寄存器中读取数据
{ serialPort.Open();
buffer1 = mmodbus.asciiGetCommandSend(command1[0], command1[2], command1[3], command1[4], command1[5]);
string sstr = Convert.ToBase64String(buffer1);
serialPort.WriteLine(sstr); Thread.Sleep(2000); command2 = Convert.FromBase64String(serialPort.ReadLine());
byte[] num = new byte[1024];
int j = 0;
for (int i = 4; i < command2.Length; i++)
{
num[j] = command2[i];
j++;
} buffer2 = mmodbus.asciiGetCommandResponse(command2[0], command2[2], num); if (buffer1[buffer1.Length - 2] != buffer2[buffer2.Length - 2])
{
MessageBox.Show("数据传输有误!");
break;
} string sres = "";
for (int i = 1; i < buffer2.Length - 2; i++)
{
sres += Convert.ToString(buffer2[i]);
}
responsebox.Text = sres;
serialPort.Close();
break;
} case 6: //=================function=0X03,即从寄存器中读取数据
{
serialPort.Open();
buffer1 = mmodbus.asciiPutCommandSend(command1[0], command1[2], command1[3], command1[4], command1[5]);
string sstr = Convert.ToBase64String(buffer1);
serialPort.WriteLine(sstr); Thread.Sleep(2000); command2 = Convert.FromBase64String(serialPort.ReadLine());
buffer2 = mmodbus.asciiPutCommandResponse(command2[0], command2[2], command2[3], command2[4], command2[5]); if (buffer1[buffer1.Length - 2] != buffer2[buffer2.Length - 2])
{
MessageBox.Show("数据传输有误!");
break;
} string sres = "";
for (int i = 1; i < buffer2.Length - 2; i++)
{
sres += Convert.ToString(buffer2[i]);
}
responsebox.Text = sres;
serialPort.Close();
break;
} }
} private void Form1_Load(object sender, EventArgs e)
{
initPortmessage(boudbox.Text, databitsbox.Text, portbox.Text);
} }
}
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} /*********************************************初始化串口信息*********************************************************************/
private void initPortmessage(string baud, string databits, string portname)
{
serialPort.BaudRate = Convert.ToByte(baud);
serialPort.DataBits = Convert.ToByte(databits);
//serialPort.Parity = paritybox.Text;
//serialPort.StopBits = (int)(stopbitsbox.Text);
serialPort.PortName = portname;
} //*******************************************指令的标准输入为每个信息字符必须以两位的16进制数表示*******************************/
private byte[] stringto16int(string str)
{
char[] cstr = str.ToCharArray();
byte[] buf = new byte[1024];
string ss;
int j = 0;
for (int i = 0; i < cstr.Length; i=i+2) //**********指令的标准输入为每个信息字符必须以两位的16进制数表示,范围0——F;
{
ss = Convert.ToString(cstr[i]) + Convert.ToString(cstr[i+1]);
buf[j] = Convert.ToByte(ss);
j++;
} return buf;
}
/********************************************定时触发的发送/读取数据事件*********************************************************/
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] buffer1 = new byte[1024]; //=================根据通信协议规则生成的命令代码,将发送到缓冲区的内容
byte[] buffer2 = new byte[1024];
Modbus mmodbus = new Modbus(); byte[] command1 = new byte[1024]; //**********输入信号的命令
byte[] command2 = new byte[1024]; //**********响应信号的命令
command1 = stringto16int(readbox.Text);
switch (command1[1]) //================ 根据功能位function code 决定执行读/写操作
{
case 3: //=================function=0X03,即从寄存器中读取数据
{ serialPort.Open();
buffer1 = mmodbus.asciiGetCommandSend(command1[0], command1[2], command1[3], command1[4], command1[5]);
string sstr = Convert.ToBase64String(buffer1);
serialPort.WriteLine(sstr); Thread.Sleep(2000); command2 = Convert.FromBase64String(serialPort.ReadLine());
byte[] num = new byte[1024];
int j = 0;
for (int i = 4; i < command2.Length; i++)
{
num[j] = command2[i];
j++;
} buffer2 = mmodbus.asciiGetCommandResponse(command2[0], command2[2], num); if (buffer1[buffer1.Length - 2] != buffer2[buffer2.Length - 2])
{
MessageBox.Show("数据传输有误!");
break;
} string sres = "";
for (int i = 1; i < buffer2.Length - 2; i++)
{
sres += Convert.ToString(buffer2[i]);
}
responsebox.Text = sres;
serialPort.Close();
break;
} case 6: //=================function=0X03,即从寄存器中读取数据
{
serialPort.Open();
buffer1 = mmodbus.asciiPutCommandSend(command1[0], command1[2], command1[3], command1[4], command1[5]);
string sstr = Convert.ToBase64String(buffer1);
serialPort.WriteLine(sstr); Thread.Sleep(2000); command2 = Convert.FromBase64String(serialPort.ReadLine());
buffer2 = mmodbus.asciiPutCommandResponse(command2[0], command2[2], command2[3], command2[4], command2[5]); if (buffer1[buffer1.Length - 2] != buffer2[buffer2.Length - 2])
{
MessageBox.Show("数据传输有误!");
break;
} string sres = "";
for (int i = 1; i < buffer2.Length - 2; i++)
{
sres += Convert.ToString(buffer2[i]);
}
responsebox.Text = sres;
serialPort.Close();
break;
} }
} private void Form1_Load(object sender, EventArgs e)
{
initPortmessage(boudbox.Text, databitsbox.Text, portbox.Text);
} }
}
解决方案 »
- C#水晶报表
- josn的序列化例子,未能加载文件或程序集“System.Runtime.Serialization,或它的某一个依赖项。系统找不到指定的文件
- 哪位兄弟有物料管理系统的源码,谢谢了。
- 关于一个正则表达式
- 关于数据库
- 为什么我自己定义的控件不能显示ToolTip?
- 为什么Hashtable里的Item属性不见了???
- 如何截取一段字符串碰到第一个非汉字的字符的时候停止截取
- vs2012 IDE 遇到怪事了,所有config文件都打不开!求解啊
- c# richtextbox指定位置插入图片
- 一个调试windows service的问题,急
- C#中关于grid控件如何写删除数据库代码?
responsebox.Invoke(new MethodInvoker(delegate{responsebox.Text=sres;}));
这样就不会“假死”了
不过又有一个问题,command2 = Convert.FromBase64String(serialPort.ReadLine());提醒我“这个由于线程退出或应用程序请求,I/O 操作已中止。”,这个是怎么回事,我想在一个button_click事件中同时完成发出一条指令,并取得其设备相应指令,从中得到读取到得数据。