串口不能在C#中接收整个数据

时间:2013-07-22 00:21:27

标签: c# serial-port at-command

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

  

AT + CUSD = 1, “* 778#”,15

收到:

  

AT + CUSD = 1, “* 778#”,15

     

     

+ CUSD:0,“余额:0.00 TK。有效期:29-Jul-13。奖金:0.00TK。免费最低:0。拨打* 121 * 2092#给Ashiqui-2的3首热门歌曲作为你的来电者   Tunetk.10" ,64

但是在发送数据后的C#中

  

AT + CUSD = 1, “* 778#”,15

它返回:

  

AT + CUSD = 1, “* 778#”,15

     

     

+ CUSD:0,“余额:0.00 TK。有效期:29-Jul-13。奖金:0.00TK。免费最低:0。拨打* 121 * 2092#给Ashiqui-2的3首热门歌曲作为你的来电调

这意味着在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");
            }
        }

2 个答案:

答案 0 :(得分: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后,我发现this remark

  

此方法以字符串形式返回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);
        }
    }
}

答案 1 :(得分:1)

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

// e.g. I normally used (carriage return + newline) instead of just either one
sp1.NewLine = "\r\n";