我正在使用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");
}
}
答案 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";