最近做了一个GPRS模块的简单测试,其中短消息方式比较简单,同时也与其他GPRS模块通用,现在将我的调试笔记写下来。
短消息方式:
一、与短信相关的 AT 指令
AT+CMGC Send an SMS command(发出一条短消息命令)
AT+CMGD Delete SMS message(删除 SIM 卡内存的短消息)
AT+CMGF Select SMS message formate (选择短消息信息收发格式: 0-PDU;1-文本)
AT+CMGL List SMS message from preferred store(列出 SIM 卡中的短消息
AT+CMGR Read SMS message(读短消息)
AT+CMGS Send SMS message(发送短消息)
AT+CMGW Write SMS message to memory(向 SIM 内存中写入待发的短消息)
AT+CMSS Send SMS message from storage(从 SIN |M 内存中发送短消息)
AT+CNMI New SMS message indications(显示新收到的短消息)
AT+CPMS Preferred SMS message storage(选择短消息内存)
AT+CSCA SMS service center address(短消息中心地址)
AT+CSCB Select cell broadcast messages(选择蜂窝广播消息)
AT+CSMP Set SMS text mode parameters(设置短消息文本模式参数)
AT+CSMS Select Message Service(选择短消息服务)
发送短消息有两种方式:PDU和TEXT 模式
二、 PDU 模式下发送中英文短消息
AT+CMGF=0 //首先将短信息格式设为PDU 模式
AT+CSCS=“UCS2” //设置字符格式为UCS2 模式
AT+CSCA=”+86138XXXXXXXX”,145 //设置短消息服务中心地址
注:对于中国移动的短信服务中心号是+861380xxxx500,其中xxxx是你所在的长途电话区号,不足4位就补0,比如我所在的北京是010,补0后是0100,就应该+8613800100500。
[PDU]数据单元格式定义为:
以下例子发送“你好”到13912345678
发送数据是:你好
Unicode译码为:4F60597D
AT+CMGS=019 //15(PDU 规约头固定长度 15 字节)+4(报文长度 4 个字节)
> 0011000D91683119325476F8000801044F60597D [ctrl-Z]
00 //为SCA预留
11 // FO 设置PDU 类型
00 // MR 发送参考号
0D //DA 目的号码长度
91 //DA 目的号码类型
68 //DA 中国的区号
3119325476F8 //DA 目的号码编码
00 // PID 发送方式
08 //DCS 编码模式
01 //VP 有效期
PDU 中用户数据前的PDU 头的长度是15 字节
04 //UDL 数据长度
4F60597D //UD 数据内容Unicode 译码
例子中目的号码是一种内存编码方式,将每两位数据位置互换,余下最后单位的补 F ,如13912345678 编码为3119325476F8。用户使用PDU 模式发送中文短消息时只需按照上述例子,改变 TPDU 的十进制长度、手机号码编码、报文长度和报文内容Unicode 译码即可。
设置DCS 编码模式改变短消息发送等级:
按照GSM08.38 协议约定,PDU 中的DCS 字段(Bit7…0)用于设置短消息内容的编码方式 和发送等级, 具体为Bit4 用于决定Bit1 和 Bit0 的设置是否有效 (1 为有效, 0 为无效) ;Bit1和Bit0 均设置为0 表示短消息发送等级为0 等级, 即直接发送至终端而不存放在SIM卡; Bit3 设置为 1 且Bit2 设置为 0 表示短消息内容为 UCS2 编码。上例中 DCS 字段为 08,即表示短消息内容为 UCS2 编码且无发送等级;若改为 18 则表示短消息内容为 UCS2 编码且按0 等级发送,即直接发送至目的终端。
三、TEXT 模式发送短消息
TEXT模式只支持传送英文及数字信息,但它的编码要比PDU模式简单很多,所以建议采用TXET模式发送和接受短消息。
1、TEXT模式下发送中文短消息
AT+CMGF=1 //首先将短信息格式设为 TEXT 模式
AT+CSCS=“UCS2” //设置字符格式为UCS2 模式:
AT+CSCA=”+86138XXXXXXXX”,145 //设置短消息服务中心地址
注:对于中国移动的短信服务中心号是+861380xxxx500,其中xxxx是你所在的长途电话区号,不足4位就补0,比如我所在的北京是010,补0后是0100,就应该+8613800100500。
AT+CSMP=17,167,0,24 //设置短消息发送相关参数:四参数分别为 FO、VP、PID 和 DCS,代表意义与 PDU 模式中参数相同,不同的是须以十进制表示,24 表示短消息内容为 UCS2 编码且直接发送至目的终端,如改为 25 则表示短消息内容为 UCS2 编码且发送至SIM 卡存储。
发送:AT+CMGS= 手机号码编码[CR]
收到[>]响应后再发送
[报文内容Unicode 译码][ctrl-Z]
以下例子发送“你好”到13912345678
发送数据是:你好
Unicode译码为:4F60597D
AT+CMGS=” 00310033003900310032003300340035003600370038” //直接输入手机号码编码
> 4F60597D [ctrl-Z]
用户使用TEXT 模式发送中文短消息时只需按照上述例子,改变手机号码编码和报文内容的Unicode 译码即可。
2、TEXT模式下发送英文短消息
AT+CMGF=1 //首先将短信息格式设为 TEXT 模式
AT+CSCS=“GSM” //设置字符格式为GSM 模式
AT+CSCA=”+86138XXXXXXXX”,145 //设置短消息服务中心地址
注:对于中国移动的短信服务中心号是+861380xxxx500,其中xxxx是你所在的长途电话区号,不足4位就补0,比如我所在的北京是010,补0后是0100,就应该+8613800100500。
AT+CSMP=17,167,0,240 //设置短消息发送相关参数:四参数分别为 FO、VP、PID 和DCS,代表意义与PDU 模式中参数相同,不同的是须以十进制表示,240 表示短消息内容为默认 GSM 编码且直接发送至目的终端,如改为 241 则表示短消息内容为 GSM 编码且发送至SIM 卡存储。
发送:AT+CMGS= “13XXXXXXXXX” [CR]
收到[>]响应后再发送
[报文内容][ctrl-Z]
以下例子发送“Hello”到13912345678
报文是:Hello
AT+CMGS=” 13912345678” //直接输入手机号码
> Hello [ctrl-Z]
使用TEXT 模式发送英文短消息时只需按照上述例子,改变手机号码和报文内容即可。
以上为如何发送短信的方法,那又如何接受刚收到的短消息呢?接受刚收到的短消息有两种方法:查询终端方式和使用事件方式。查询方式是先不处理网络上 发来的信息,定期使用“AT+CMGL=0”命令读取未读取的短信,如果有就读入,交给上级程序处理。然后将此短消息删除,该方法简单,但许多时候都在做 无用功,效率低下。实际中我们使用事件方式,通过AT+CNMI指令设置接收到的短信息存储到SIM卡,并返回提示信息。
短消息类(class)的概念:根据指定储存的位置,短消息分为class 0 - 3四个类。也可以不指定类(no class),由ME按默认设置进行处理,存储到内存或者SIM卡中。在TPDU的TP-DCS字节中,当bit7-bit4为00x1, 01x1, 1111时,bit1-bit0指出消息所属类:
00 - class 0:只显示,不储存
01 - class 1:储存在ME内存中
02 - class 2:储存在SIM卡中
03 - class 3:直接传输到TE
GSM Modem一般都支持一条“AT+CNMI”指令,可用于设定当有某类短消息到达时,如何处置它:只储存在指定的内存(易失的/非易失的)中,先储存后通知TE,还是直接转发到TE,等等。
"AT+CNMI"指令语法为
AT+CNMI=[<mode>[,<mt>[,<bm>[,<ds>[,<bfr>]]]]]
mode - 通知方式:
0 - 不通知TE。
1 - 只在数据线空闲的情况下,通知TE;否则不通知TE。
2 - 通知TE。在数据线被占用的情况下,先缓冲起来,待数据线空闲,再行通知。
3 - 通知TE。在数据线被占用的情况下,通知混合在数据中一起传输。
mt - 消息储存或直接转发到TE:
0 - 储存到默认的内存位置(包括class 3)
1 - 储存到默认的内存位置,并且向TE发出通知(包括class 3)
2 - 对于class 2,储存到SIM卡,并且向TE发出通知;对于其它class,直接将消息转发到 TE
3 - 对于class 3,直接将消息转发到 TE;对于其它class,同mt=1
bm, ds, bfr的含义,请参考相关标准文档。一般不需要去关心它们。
在程序中具体实现时,使用mode=2, mt="1",即AT+CNMI=2,1,0,0,0:比较简单。对所有类型的短消息,只要在收到ME送来的"+CMTI"通知后,用"AT+CMGR"指令读取消息内容就行了。
举例如下:
(蓝色表示PC机发送的数据,红色表示模块返回的数据)
AT+CMGF=1 //设置短消息格式为TEXT格式
OK
AT+CCS=”CSM” //设置字符格式为GSM模式
OK
AT+CSCA=”+8613800100500”,145 //设置短消息服务中心地址
OK
AT+CNMI=2,1,0,0,0 //设置收到新短信存于SIM卡中并发CMTI通知
OK
+CMTI:”SM”,1 //收到了短信,自动弹出,其中1表示存在SIM中的序号
AT+CMGR=1 //读取短信,其中1要与上面序号对应
+CMGR:”REC UNREAD”,”8615810533873”,,”09/04/30,10:59:17+32”,145,36,0,0”8613800100500”,145,5
ABCD //收到来自手机15810533873的短信,内容为ABCD
OK
AT+CMGD=1 //删除短信,其中1为短信序号