使用.NET中的RS422传输数据

时间:2010-01-27 14:39:20

标签: c# serial-port

我正在尝试制作一个简单的应用程序来测试与另一台计算机的RS422通信。使用RS232接口,该程序运行顺畅,但RS422无法正常工作,因为有一台计算机无法发送。为了使场景复杂一点,我可以使用超级终端通过RS422进行通信。

以下是代码:

public partial class MainForm : Form
{
    private SerialPort m_port;

    public MainForm()
    {
        InitializeComponent();
        m_list.Items.AddRange(SerialPort.GetPortNames());

        m_port = new SerialPort();
        m_port.BaudRate = 9600;
        m_port.DataBits = 8;
        m_port.Parity = Parity.None;
        m_port.StopBits = StopBits.One;
        m_port.Handshake = Handshake.None;
        m_port.Encoding = new ASCIIEncoding();

        m_port.ReceivedBytesThreshold = 1;
        m_port.DataReceived += DataReceivedEvent;
    }

    ~MainForm()
    {
        if (m_port != null)
            m_port.Close();
    }

    private void openClick(object sender, EventArgs e)
    {
        m_port.Close();
        m_port.PortName = (string)m_list.SelectedItem;

        try
        {
            m_port.Open();
            m_buttonSend.Enabled = true;
        }
        catch (UnauthorizedAccessException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void ButtonSendClick(object sender, EventArgs e)
    {
        m_port.WriteLine(m_testBox.Text);
    }

    private void DataReceivedEvent(object sender, SerialDataReceivedEventArgs args)
    {
        Invoke(new EventHandler(DoUpdate));
    }

    private void DoUpdate(object s, EventArgs e)
    {
        m_receivedText.Text += m_port.ReadLine();
    }
}

对此技术的任何帮助或经验表示赞赏。谢谢!

修改

Hyperterminal的Portmon跟踪与.NET组件之间存在很多差异。有一条线引起我的注意,因为它依赖于端口中断IOCTL_SERIAL_SET_WAIT_MASK的等待掩码。

使用超级终端:

IOCTL_SERIAL_SET_WAIT_MASK  Serial0  SUCCESS  Mask: RLSD ERR

使用.NET SerialPort组件

IOCTL_SERIAL_SET_WAIT_MASK  Serial0  SUCCESS  Mask: RXCHAR RXFLAG CTS DSR RLSD BRK ERR RING     

有谁知道如何从组件中更改掩码?这变得越来越深......

1 个答案:

答案 0 :(得分:1)

最后在初始化时出现问题,另一个出现阻塞ReadLine调用问题。必须启用RTS和DTS。

这是代码

using System;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;

namespace ComPlay
{
    public partial class MainForm : Form
    {
            private SerialPort m_port;
            private byte [] m_buffer = new byte[10];

            public MainForm()
            {
                    InitializeComponent();
                    m_list.Items.AddRange(SerialPort.GetPortNames());
                    m_list.SelectedIndex = 0;

                    m_port = new SerialPort(SerialPort.GetPortNames()[0],9600,Parity.None,8,StopBits.One);   
                    m_port.Handshake = Handshake.None;
                    m_port.RtsEnable = true;
                    m_port.DtrEnable = true;

                    m_port.DataReceived += DataReceivedEvent;
                    m_port.PinChanged += PinChangedEvent;
            }

            ~MainForm()
            {
                    if (m_port != null)
                            m_port.Close();
            }

            private void openClick(object sender, EventArgs e)
            {
                    if (m_port.IsOpen)
                            m_port.Close();

                    m_port.PortName = (string)m_list.SelectedItem;

                    try
                    {
                            m_port.Open();
                            m_buttonSend.Enabled = true;
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                            MessageBox.Show(ex.Message);
                    }
            }

            private void ButtonSendClick(object sender, EventArgs e)
            {
                    byte [] r_bytes = Encoding.ASCII.GetBytes(m_testBox.Text);
                    m_port.Write(r_bytes,0,r_bytes.Length);
            }

            private void DataReceivedEvent(object sender, SerialDataReceivedEventArgs args)
            {
                    Invoke(new EventHandler(DoUpdate));
            }

            private void DoUpdate(object s, EventArgs e)
            {
                    m_port.Read(m_buffer, 0, m_buffer.Length);
                    m_receivedText.Text += Encoding.ASCII.GetString(m_buffer); 
            }

            private void PinChangedEvent(object sender, SerialPinChangedEventArgs args)
            {

            }
    }
}

开始传播的重要一点是改变这个

IOCTL_SERIAL_SET_HANDFLOW Serial1 SUCCESS Shake:80000000 Replace:80000040 XonLimit:1024 XoffLimit:1024

到这个

IOCTL_SERIAL_SET_HANDFLOW Serial1 SUCCESS Shake:80000001 Replace:80000040 XonLimit:1024 XoffLimit:1024

激活RTS和DTR。