9

我正在使用 AT 命令在 C#.Net 中为 GSM 调制解调器(D-Link DWM-156)开发应用程序。我在发送 Unicode 消息(例如用波斯语或阿拉伯语编写的消息)时遇到问题。这是我的程序的核心:

SerialPort GSMPort = new SerialPort();

GSMPort.PortName = "COM6";
GSMPort.BaudRate = 9600;
GSMPort.Parity = Parity.None;
GSMPort.DataBits = 8;
GSMPort.StopBits = StopBits.One;
GSMPort.Handshake = HandShake.RequestToSend;
GSMPort.DtrEnable = true;
GSMPort.RtsEnable = true;

GSMPort.Open();

GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write(shortMessage+ "\x1A");

它适用于英文和 ASCII 字母。我已经阅读了这篇文章,并且可以使用 AT 命令在超级终端中发送 Unicode 消息:

AT [Enter]
OK
AT+CSCS="UCS2" or AT+CSCS="HEX" [Enter] ---> We have to convert our message to hex 
OK
AT+CMGF=1 [Enter]
OK
AT+CMGS="destinationNumber" [Enter]
> 0633064406270645002006450631062D06280627 ---> The hex format of our message (سلام مرحبا)
+CMGS: 139
OK

由于此命令正常工作,我已将其添加GSMPort.Write("AT+CSCS=\"UCS2\"\r");到我的应用程序中,并尝试发送0645 0631 062D 0628 0627 (مرحبا) 或0633 0644 0627 0645 (سلام)。

GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A");

但与超级终端中的 AT 命令不同,目的地没有收到正确的字母。C# 代码和超级终端代码中的这些 AT 命令有什么区别?如果您能帮我解决这个问题,我将不胜感激。


附加信息: 如您所知,通过超级终端和使用 AT 命令发送 Unicode 消息(例如波斯字母)没有问题。在下面的代码中,我尝试发送سلام,“0633064406270645”是它的十六进制形式。但我的手机收到□□□□。

GSMPort.Encoding = UnicodeEncoding.GetEncoding(1256);
GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A");

另一方面,在超级终端环境中,一切正常,我收到了سلام。

AT [Enter]
OK
AT+CSCS="UCS2"
OK
AT+CMGF=1 [Enter]
OK
AT+CMGS="destinationNumber" [Enter]
> 0633064406270645 [Ctrl+Z]
+CMGS: 139
OK

我注意到,如果我在超级终端属性中检查“发送行以换行符结尾”(它在属性->设置-> ASCII 设置中,请查看下图),我将遇到与我相同的问题C# 代码。GSMPort.Write我认为默认情况下启用“以换行符发送行结束” ?如果是,我该如何禁用它?

在此处输入图像描述

4

3 回答 3

10

我终于找到了解决这个问题的方法。正如我在问题的“附加信息”部分中所说,发送以换行符结尾的行会导致SerialPort超级终端中用于发送 Unicode 消息的 C# 和 AT 命令之间的这种不匹配。我刚刚\r\n换行符替换。修改后的代码如下:

GSMPort.Write("AT\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A"); 

保持SerialPort.EncodingSerialPort.NewLine属性不变。无需更改它们的默认值,只需设置AT+CSCS="UCS2"为以 Unicode 格式发送消息即可。

于 2013-03-16T15:10:18.540 回答
4

首先检查您的调制解调器支持unicode,然后将您的代码更改为此
我们必须为 Unicode 消息指定正确的 DCS(数据编码方案),即 0x08。

我们可以通过将 AT+CSMP 命令的第四个参数更改为“8”来设置该值:

AT+CSMP=1,167,0,8

    GSMPort.Write("AT\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CSCS=\"UCS2\"\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CMGF=1\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CSMP=1,167,0,8\r"); //AT+CSMP=1,167,0,8
    Thread.Sleep(1000);
    GSMPort.WriteLine("AT+CMGS=\"" + destinationNumber + "\"\r\n");
    Thread.Sleep(1000);
    GSMPort.WriteLine("0633064406270645" + "\x1A");
于 2013-03-09T15:48:12.293 回答
2

的默认编码SerialPortEncoding.ASCII. 设置SerialPort.Encoding为一种编码以支持您正在使用的字符集(如Encoding.UTF32),或者SerialPort.Write(char[], int, int)以任何喜欢的方式使用您的 Unicode 字符串并将其转换为字节。

于 2013-03-09T15:03:02.477 回答