RS485 通信 modbus RTU通信问题,上位机无法读取数据。

文光山石 2016-06-02 07:39:16
本人用vb.net写了一个上位机软件,就是读不到数据,但是用串口调试程序读得到。
于是我重新用VB.net c# vb6 都写了一个测试通信的小程序,用同一个串口,相同的串口参数(38400,8,N,2 ,串口设置为接收到一个字节就引发事件,二进制格式发送数据) 和下位机,测试发现vb.et 和c#的都不行,vb6的可以正常通信。而且我用两个串口直接对接,一头连接vb.net 测试程序,一头连接串口调试软件,两头收发都正常,c#和vb6这样连接也可以正常通信。就是一头连接测试程序,一头连接下位机,c#和vb.net的都不通,都是可以发送,但是没有任何数据返回,没有触发串口接收数据事件,vb6的就可以正常通信。
难道 .net 的IO.Ports.SerialPort 类有问题,没有vb6的mscomm 控件稳定。
还是我的代码有问题?求大神帮忙分析。
vb.net 主要代码

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
COM1.BaudRate = 38400
COM1.DataBits = 8
COM1.StopBits = 2
COM1.Parity = IO.Ports.Parity.None

Dim ports As String() = IO.Ports.SerialPort.GetPortNames() '用SerialPort,获取计算机的有效串口
Dim port As String
For Each port In ports
ComboBox1.Items.Add(port) '向combobox中添加项
Next port

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'打开串口
Try
COM1.PortName = ComboBox1.Text
COM1.Open()

Catch ex As Exception
TextBox2.Text = ex.Message
End Try
End Sub

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
'发送按钮
Dim data(20) As Byte
data(0) = &HA
data(1) = 1
data(2) = 3
data(3) = &HE7

data(4) = 0
data(5) = &H27
data(6) = &HCD
data(7) = &H18

Dim a() As String
a = TextBox1.Text.Split(" ")
Dim CC As Integer

Try
data(0) = "&H" & a(0)
data(1) = "&H" & a(1)
data(2) = "&H" & a(2)
data(3) = "&H" & a(3)
data(4) = "&H" & a(4)
data(5) = "&H" & a(5)
Dim HL1 = Get_CRC16(data, 6)
data(6) = HL1.L
data(7) = HL1.H


If COM1.IsOpen = False Then
TextBox2.Text = "串口未打开"
Exit Sub
End If
CC = 8 '发送字节数
COM1.Write(data, 0, CC)
Static i As Integer = 0
i += 1
Button3.Text = "发送:" & i
Catch ex As Exception
Console.WriteLine(ex.Message)

TextBox2.Text = ex.Message

End Try
End Sub

Private Sub COM1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles COM1.DataReceived
'接收事件
Static cccc As Integer = 1
cm("接收:" & cccc)
cccc += 1
Dim InBytes() As Byte '读数据BUFF
Dim readCount As Integer

ReDim InBytes(105 - 1) ' ReDim InBytes(105 - 1)

Dim tmpcount As Integer = InBytes.Length '定长

If tmpcount > 50 Then
Delay_DoEvents(20 + 30) '延迟以接收数据
End If
readCount = COM1.Read(InBytes, 0, tmpcount)
COM1.DiscardInBuffer()
showdata(InBytes) '显示到文本框
End Sub


C#主要代码

private void Form1_Load(object sender, EventArgs e)
{
this.COM1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(COM1_DataReceived);
this.COM1.BaudRate = 38400;
this.COM1.DataBits = 8;
this.COM1.StopBits = StopBits.Two;
this.COM1.Parity = Parity.None;
String[] ports = System.IO.Ports.SerialPort.GetPortNames();// 用SerialPort,获取计算机的有效串口
// String port;
foreach (String port in ports)
{
comboBox1.Items.Add(port);//'向combobox中添加项
}
}

private void button1_Click(object sender, EventArgs e)
{
try
{
this.COM1.PortName = this.comboBox1.Text;
this.COM1.Open();
}
catch (Exception ex)
{
this.textBox2.Text = ex.Message;
}
}

private void button3_Click(object sender, EventArgs e)
{
int num;
int num3;
byte[] buffer = new byte[0x15];
string[] strArray = this.textBox1.Text.Split(new char[] { ' ' });
try
{
buffer[0] = Convert.ToByte(strArray[0], 16);
buffer[1] = Convert.ToByte(strArray[1], 16);
buffer[2] = Convert.ToByte(strArray[2], 16);
buffer[3] = Convert.ToByte(strArray[3], 16);
buffer[4] = Convert.ToByte(strArray[4], 16);
buffer[5] = Convert.ToByte(strArray[5], 16);
HL hl = this.Get_CRC16(buffer, 6);
buffer[6] = hl.L;
buffer[7] = hl.H;
this.COM1.Write(buffer, 0, 8); //发送8个字节
c++;
this.button3.Text = "发送 " + c;
}
catch (Exception exception1)
{
this.textBox2.Text = exception1.Message;
}
}

private void COM1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[0x69];
int length = buffer.Length;
if (length > 50)
{
this.Delay_DoEvents(50L);//延迟
}
int num = this.COM1.Read(buffer, 0, length);
this.COM1.DiscardInBuffer();
this.showdata(buffer);//显示数据
}


vb6的跟vb.net 代码差不多就是控件不一样。


...全文
1625 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

If COM1.IsOpen = False Then
                TextBox2.Text = "串口未打开"
                Exit Sub
            End If
这句我觉得放Load事件比较好吧。然后在打开串口里设置textbox2.text="串口已连接" 发送按钮我觉得该这样:

try
  if com1.isopen=true then
    …………(date(0-7))
     CC = 8   '发送字节数
            COM1.Write(data, 0, CC)
            Static i As Integer = 0
            i += 1
            Button3.Text = "发送:" & i
        Catch ex As Exception
            Console.WriteLine(ex.Message)
 
            TextBox2.Text = ex.Message
 
        End Try
lylkr 2016-06-03
  • 打赏
  • 举报
回复
上位机如果是usb转串口,换成板载或扩展卡扩展,或vb.net里用vb6.0的串口控件 c#没用过 vb.net我也碰到过类似情况,就是真么解决的

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧