【问题标题】:How to send command to RS232 serial port?如何向 RS232 串口发送命令?
【发布时间】:2021-11-26 10:14:24
【问题描述】:

我最近得到了一张 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。

【问题讨论】:

  • 术语“执行固件”在这里具有误导性(听起来您想将新固件闪存到设备上,或者可能将代码加载到 RAM 中并即时执行),这就是为什么我更新了你的问题的标题。固件在您为卡通电的那一刻执行。您要做的是通过它公开的串行控制台接口与(已经运行的)固件进行交互。

标签: c# console serial-port firmware .net-framework-4.8


【解决方案1】:

您正在发送字符串 Enter(例如输入 ⇧E、N、T、E,R)。您可能应该发送 ⏎ Enter key,它在终端上以 ASCII 码 13 表示,即 C# 字符串中的 \r。

您还没有发送任何实际命令。试试counters\r 或sys\r。

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

我还建议在发送任何数据之前为接收到的数据添加事件侦听器,否则会出现竞争情况,在您设置侦听器之前卡可能会响应,您会丢失部分数据。


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

根据docs:

不保证每收到一个字节都会引发 DataReceived 事件。使用BytesToRead 属性确定缓冲区中还有多少数据需要读取。

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

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

这是我的一般做法:

对流数据使用事件驱动 (DataReceived) 代码。也就是说,数据会定期交付,而无需源自您的应用程序的特定关联命令。

对命令/响应协议使用轮询。这些可能涉及您创建的用于轮询的线程,但更常见的是简单的循环,可能会或可能不会阻塞其他操作,直到它们完成。 p>

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

【讨论】:

  • 我在控制台应用程序上更改了代码。执行结果出现bp1>。按enter键后,应用程序关闭。如何连续接受命令并接收命令结果?只需要继续添加 mySerialPort.DataReceived 事件?
  • 添加一次事件处理程序就足够了。只是不要退出你的程序——例如,如果你想每秒查询一次counters,创建一个循环休眠 1 秒然后发送counters\r,一遍又一遍。
  • 对不起,我的错。问题的单词continuously 是synchronously。我刚刚得到 sys 命令结果,但它没有显示出来。我必须关闭应用程序并重新打开它。结果会显示出来。
  • 还只是为了确保:在发送命令之后发送回车键 (\r),对吗?不是反过来吗?你说你收到了bp1> 但没有sys 响应,这表明你发送了一个空命令(就像之前没有命令的\r),这就是我问的原因......并且“下次出现" 如果它在那时提交上一次运行的命令也很有意义......确保你发送sys\r 而不是\rsys。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
相关资源
最近更新 更多