Передача данных с RS422 в .NET - PullRequest
3 голосов
/ 27 января 2010

Я пытаюсь создать простое приложение для проверки связи RS422 с другим компьютером. Используя интерфейсы RS232, эта программа работает без сбоев, но с RS422 не работает, так как есть один компьютер, который не может отправить. Чтобы немного усложнить сценарий, я могу общаться через RS422 с помощью HyperTerminal.

Вот код:

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();
    }
}

Любая помощь или опыт с этой технологией приветствуется. Спасибо!

EDIT

Существует много различий между трассировкой с Portmon Гипертерминала и компонентом .NET. Одна из линий привлекла мое внимание, так как она относится к маске ожидания прерывания порта IOCTL_SERIAL_SET_WAIT_MASK.

С HyperTerminal:

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 Ответ

1 голос
/ 28 января 2010

Наконец возникла проблема с инициализацией, а другая - с блокирующим вызовом 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...