0

我正在使用 C# 串行端口控制 gsm 调制解调器。现在在 Mikroelectronia USART 终端中发送后:

AT+CUSD=1,"*778#",15

它接收:

AT+CUSD=1,"*778#",15

好的

+CUSD: 0,"余额: 0.00 TK. 有效期: 29-Jul-13. Bonus: 0.00TK. Free Min: 0. 拨打 *121*2092# 获取 Ashiqui-2 的 3 首热门歌曲作为你的 Caller Tunetk.10" ,64

但是在C#中发送数据后

AT+CUSD=1,"*778#",15

它返回:

AT+CUSD=1,"*778#",15

好的

+CUSD: 0,"Balance: 0.00 TK. 有效期: 29-Jul-13. Bonus: 0.00TK. Free Min: 0. 拨打 *121*2092# 获取 Ashiqui-2 的 3 首热门歌曲作为您的 Caller Tune

这意味着在 C# 中,它在“Caller Tune”之后不会收到任何数据。为什么会这样?我使用的部分 C# 代码是

        private void Form1_Load(object sender, EventArgs e)
        {
            sp1.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
        }

        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var valueOfPort = sp1.ReadExisting();
            textBox1.AppendText(valueOfPort);

        }
 private void button1_Click(object sender, EventArgs e)
        {
            TextBox.CheckForIllegalCrossThreadCalls = false;

            try
            {


                if (!sp1.IsOpen)
                {
                    sp1.Open();
                }
                sp1.Write(textBox2.Text+"\r");

            }
            catch(Exception ex)
            {

                MessageBox.Show(string.Format("Exception : {0}", ex.Message), "Port Error");
            }
        }
4

2 回答 2

3

TextBox.CheckForIllegalCrossThreadCalls = false;让我非常怀疑,我认为这就是破坏你的程序的原因,只需调用以正确更新文本框,我认为它会起作用。只需将事件代码更改为以下内容:

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if(textbox1.InvokeRequired)
    {
        textbox1.Invoke(new SerialDataReceivedEventHandler(sp_DataReceived), sender, e);
    }
    else
    {
        var valueOfPort = sp1.ReadExisting();
        textBox1.AppendText(valueOfPort);
    }
}

这将检查您是否在正确的线程上运行,如果不是,它将使用相同的参数在 UI 线程上再次重新启动该函数。也一定要删除TextBox.CheckForIllegalCrossThreadCalls = false;


更新:重新阅读 MSDN 后,我发现了这个评论

此方法以字符串形式返回 SerialPort 对象的流和内部缓冲区的内容。此方法不使用超时。请注意,此方法可能会在内部缓冲区中留下尾随前导字节,这会使 BytesToRead 值大于零。

尝试检查调用后是否还有更多数据要读取ReadExisting

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if(textbox1.InvokeRequired)
    {
        textbox1.Invoke(new SerialDataReceivedEventHandler(sp_DataReceived), sender, e);
    }
    else
    {
        while(sp1.BytesToRead > 0)
        {
            var valueOfPort = sp1.ReadExisting();
            textBox1.AppendText(valueOfPort);
        }
    }
}
于 2013-07-22T00:31:33.283 回答
1

您是否已定义设备的 EOL 并在程序中正确设置?C# 串行端口不一定会在消息开始时启动 DataReceive,也不知道消息在哪里结束。它可以在消息的任何地方终止。您应该尝试显式设置可以由端口唯一标识的 EOL,以便它缓冲传入消息并在完成后返回它。

// e.g. I normally used (carriage return + newline) instead of just either one
sp1.NewLine = "\r\n";
于 2013-07-22T00:31:54.520 回答