新鸟初学C# 想用SerialPort控件实现Modbus通信协议 读取/写入数据 求大侠指点
小弟正在学习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);
}
}
} --------------------编程问答-------------------- 在发送和接受的实践中,如果你要将接受到的信息显示在textbox中,要用到委托,否则会出现假死。
responsebox.Invoke(new MethodInvoker(delegate{responsebox.Text=sres;}));
这样就不会“假死”了 --------------------编程问答-------------------- 3Q,假死的问题解决了,非常感谢
不过又有一个问题,command2 = Convert.FromBase64String(serialPort.ReadLine());提醒我“这个由于线程退出或应用程序请求,I/O 操作已中止。”,这个是怎么回事,我想在一个button_click事件中同时完成发出一条指令,并取得其设备相应指令,从中得到读取到得数据。
补充:.NET技术 , C#