如何向RS232串口发送指令?

How to send command to RS232 serial port?

我最近得到了一张 sas 扩展卡。

给我卡的人说:

芯片上有固件,可以显示传感器的温度。

他要我开发一个C#Console app来执行固件

我不知道固件源代码是什么样子的。

但它可以由 PuTTy 执行,它的连接是通过 RS232 串行端口。

PuTTy 连接设置:

点击 Open 后,按 Enter 并输入命令 sys:

我在 C# 代码中的尝试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Threading;


namespace SerialPortExample
{
    class SerialPortProgram
    {
        // Create the serial port with basic settings
        [STAThread]
        static void Main()
        {
           
           
            SerialPort mySerialPort = new SerialPort("COM5");

            mySerialPort.BaudRate = 115200;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.RtsEnable = true;
            mySerialPort.DtrEnable = true;
            mySerialPort.ReadTimeout = 2000;
            mySerialPort.WriteTimeout = 1000;
            mySerialPort.Open();
            if(mySerialPort.IsOpen)
            { 
                string str= "Enter";
                mySerialPort.Write(str);
 
            }
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            
            Console.ReadLine();
            
        }
        private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            Console.WriteLine("Data Received:");
            Console.Write(indata);
        }


    }
}

我的代码执行了什么:

我的代码有什么问题?

如何通过 RS232 执行固件并像 PuTTy 那样进行交互?

我的控制台应用正在使用 .Net Framework 4.7.2

您正在发送字符串 Enter(例如键入 ENTER)。您可能应该发送 ⏎ Enter key,它在终端上以 ASCII 代码 13 表示,即 C# 中的 \r字符串.

此外,您还没有发送任何实际命令。尝试 counters\rsys\r.

(您目前收到 Enter 作为响应,因为那是您发出的内容,卡片会回显任何传入的字符,因此它可以像 shell 一样使用而无需盲打。有还没有其他响应,因为从卡片的角度来看,你基本上开始输入(无效的)命令 Enter 但尚未使用 ⏎ Enter 键提交。)

此外,我建议在发送任何数据之前为接收到的数据添加事件监听器,否则会出现竞争条件,在这种情况下,卡可能在您设置监听器之前就做出响应,并且您会丢失一部分数据。


附加说明:在您的情况下甚至可能不希望使用 DataRecieved 事件。

根据docs

The DataReceived event is not guaranteed to be raised for every byte received. Use the BytesToRead property to determine how much data is left to be read in the buffer.

这意味着 您的 DataReceived 事件可能根本不会触发 如果发送的数据总数还不够(它可能会在一段时间后触发一次查看所有数据)- 但如果在此之前退出程序,您将永远看不到。

按照建议here(强调我的):

Here is my general approach:

Use event-driven (DataReceived) code for streaming data. That is, where data is delivered at regular intervals, without specific associated commands that originate from your application.

Use polling for Command/Response protocols. These might involve a thread the you create to poll, but more frequently would be simple loops that may or may not block other operations until they complete.

因此,建议改用 Read 方法之一(参见 docs)。还有 ReadToReadLine,您可能会发现它们很有用。例如,您可以选择使用 ReadTo(" bp1 >")