GPRS模块(MG2639)TEXT形式和PDU模式发送短消息详解(含代码片段)

GPRS模块(MG2639)TEXT模式和PDU模式发送短消息详解(含代码片段)

1.使用at命令发送短消息常用Text和PDU(Protocol   Data   Unit,协议数据单元)模式。使用Text模式收发短信代码简单,实现起来十分容易,但最大的缺点是不能发中文短信(接收到一条短信之后使用文本模式将其读出是完全可以的,只是读出的内容与使用PDU模式读出的内容有一些区别,但正文内容是完全可以获取到的);而PDU模式不仅支持中文短信,也能发送英文短信。PDU模式收发短信可以使用3种编码:7-bit、8-bit和UCS2编码。7-bit编码用于发送普通的ASCII字符,8-bit编码通常用于发送数据消息,UCS2编码用于发送Unicode字符。后文将使用具体的例子结合程序中的细节来说明一下TEXT模式和PDU模式发送短信的实例。

假设:通过串口给GPRS模块发送AT指令的函数为at_send(char *buf, int length).

2.TEXT模式发送短信

char at_cmgf[] = "at+cmgf=1\x0d";
char at_cmgs[] = "10086\x0d";
at_send(at_cmgf, sizeof(at_cmgf)-1);//set mode to TEXT mode
at_send(at_cmgs, sizeof(at_cmgs)-1);//send message length
//成功的话将会接收到">",接收到后可以输入短信正文内容
at_send("hello, world\x1a", 12);//短信正文内容

如果在send短信正文内容之后没有返回ERROR的话那短信就发送成功了,过一会儿之后模块会返回“+CMGS:”开头的一个信息。

说明:短信正文内容之后的\x1a表示的是<ctrl/Z>的ASCII码(如果是在串口调试模块的时候,只需要在短信内容之后按下ctrl+z键即可,并不需要敲回车),这个末尾是不用加\x0d的。

3.PDU模式发送短信

step1:获得短信中心号码&处理短信中心的号码可以通过at指令从模块中读取,也可以通过在网上查询得到,下面说一下用at指令从模块中读取的方法:

char at_csca[] = "at+csca?\x0d";
at_send(at_csca, sizeof(at_csca)-1);//短信中心的号码就在返回的内容中

假如获取到的短信中心的号码是:8613800230500计算短信中心号码长度,如果是奇数,那么在这个号码的末尾加上一个f(大小写都可以),然后在将号码奇数位和偶数位交换。8613800230500-->8613800230500f-->683108200305f0

然后在上面处理过的短信中心前面加上91(91是国际型)得到:91683108200305f0

短信中心号码处理的最后一步是在上面的结果前面加上短信中心的长度,长度的计算是91683108200305f0的长度除以2,这里是16/2=8(十六进制)。

因为这个长度占两个字节,所以这里自然就成了08,所以短信中心号码处理的最后结果是0891683108200305f0。

step2:手机号码的处理&处理

假设接收方的手机号码为:13512121212

前面的处理类似于短信中心号码,也是计算长度的奇偶然后判定是否要加f,最后在奇偶交换得到:3115121212f2

上面处理好的手机号码前面加上81(表示国内的号码)得到:813115121212f2

上一步的结果前面加上手机号码的长度(真实长度,不包括81以及f),这里是11位,所以为0b得到:0b813115121212f2

上一步的前面再加上00,1个字节表示移动台向短消息服务中心提交的短消息序号从0到255一般移动模块会自动改动所以默认为00 。

step3:编码格式以及有效时间设置

一般使用0008a7即可,00表示是短消息传输层作为高层协议参考或者是远程设备协同工作的标示需要服务商支持但是00H是所有服务商都支持的。

08表示编码方式为:UCS2编码0等级,这个编码方式可以传输中文。

a7表示短信的有效时间(发送短信都会到短信中心中转,如果对方无法接收短信,比如关机,超过这个有效时间之后短信中心则会丢弃这条短信)

12小时+(VP-143)*30分钟,这里的VP值就是a7

step4:短消息正文

字符串转换为Unicode代码,例如“你好”的unicode代码为 4F60597D,

前面加上短信内容长度:这里为8/2=4(十六进制)得到044F60597D以上四步完成,短信内容就已经OK了,就只剩下发送了。

step5:短信的发送

char at_cmgf[] = "at+cmgf=0\x0d";//设置为PDU模式
char at_cmgs[] = "at+cmgs=00\x0d";//短信的长度,后面会把00重新赋值
char at_msg[] = "0891683108200305f011000b813115121212f20008a7044F60597D\x1a";
at_cmgs[8] = '1';
at_cmgs[9] = '8';
at_send(at_cmgf, sizeof(at_cmgf)-1);
at_send(at_cmgs, sizeof(at_cmgs)-1);//如果成功会返回'>'
at_send(at_msg, sizeof(at_msg)-1);

发送成功的话效果与TEXT模式相同。

说明:这里的发送长度被设置为了18(这里是十进制),关于18的计算过程如下step2+step3+step4的长度之和除以2-->36/2=18

PDU模式的格式详情可以参考:http://blog.csdn.net/zixu/article/details/1527208