嵌入式GSM短信息接口的软硬件设计
PRINT "AT+CSCA=";Chr(34);"+8613800210500";Chr(34) ‘设置短信息中心号码
PRINT "AT+CMGF=1" ‘设置为Text模式
PRINT "AT+CMGS=";Chr(34);"13500123456";Chr(34) ‘发送一条短信息
PRINT "This is a test SMS";Chr(26)
PRINT "AT+CMGR=1" ‘读取收到的一条
‘短信息
.
.
.
javascript:window.open(this.src);" style="cursor:pointer;"/>
该程序使用BASCOM-AVR高级语言编写,其中PRINT语句的功能是通过URAT串行口发送字符串,Chr(34)代表ASCII字符(“),Chr(26) 代表ASCII字符(Ctrl-Z)。第一行语句设置短信息服务中心号码,即通过串口发送以下字符串: AT+CSCA= "+8613800210500",其中+8613800210500为上海地区中国移动的短信息服务中心号码。第二行语句设置短信息发送格式:AT+CMGF=1,其中1表示采用Text模式。第三和第四行语句发送一条短信息到控制中心,AT命令的格式为:AT+CMGS= "13500123456"<cr>This is a test SMS<^Z>,其中控制中心的号码为13500123456,短信息内容为“This is a test SMS”,确认控制字符为Ctrl-Z。第五行语句为读取一条收到的短信息内容:AT+CMGR=1,其中1表示收到的(在SIM卡中)第一条短信息。该指令发出后,如果GSM模块中有接收到的短信息,则从UART接口返回如下信息(具体AT命令格式请参考GSM 07.05):
+CMGR: "REC UNREAD","+8613508485560",,"02/10/16,15:37:28+32"
xxxxxxxxxxxxxxxxxx (收到短信息的文本内容)
5 基于PDU模式的中文短信息接收
发送和接收中文或中/英文混合的短信息必须采用PDU模式。根据GSM 07.05的定义,只要控制器通过UART接口向GSM模块下发AT命令,就可以直接读取收到的PDU模式的短信息:
PRINT "AT+CMGF=0" ‘设置为PDU模式
PRINT "AT+CMGR=1"‘读取接收的一条短信
‘息
在PDU模式下,GSM通信模块的回答格式为:
+CMGR: <stat>,,<length><CR><LF><pdu>
其中: stat表示该条短信息的状态,通常为0(未读过,新的短信息)或1(已读过);
Length为十进制数,表示pdu数据长度减去短信息服务中心地址长度,单位为字节;
<CR><LF>为回车换行;javascript:window.open(this.src);" style="cursor:pointer;"/>
pdu为PDU模式的数据包。
然后,要分析PDU数据包,根据PDU的数据格式将收到的中文信息和其它相关信息解析出来。
5.1 PDU数据包格式
PDU数据包由两部分构成,短信息服务中心地址(SMSC address)和TPDU,表2为PDU数据包的格式,其中一个数据单元为一个字节。
其中短信息服务中心号码、发送源号码、日期以及时间采用压缩BCD码表示,低位在前,高位在后。在本文的网络补充版(http://www.dpj.com.cn)中给出了通过读取短信息的AT命令(AT+CMGR=1)从GSM模块读到的一条PDU模式的短信息,并给出常见的数值与解释。
5.2 PDU模式的纯英文短信息解码
PDU模式的纯英文短信息编码使用GSM字符集的7位编码,此时TP-DCS的值为00。如短信息内容为英文字符“Hi”,首先将各个字符转换为7位的标准二进制ASCII码,然后要将后面字符的低位逐位调整到前面,补齐前面的差别。例如:“H”的二进制ASCII码为1001000,“i” 二进制ASCII码为1101001;显然H的二进制编码不足八位,那么就将后面字符i的最后一位补足到H的前面,就成了11001000(C8),i剩下六位110100,前面再补两个0,变成00110100(34),于是“Hi”就变成了两个八进制数 C834。由于PDU模式的纯英文短信息采用7位编码,解码不方便,因此对于只需发送和接收纯英文字符和数字符号的应用,最好采用Text模式发送和接收短信息。
表2 PDU数据包格式(接收MSM)
备注 | 名称 | 长度 | 数据单元bit位 | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
SMSC地址长度 | 1 | N+1(十六进制数) | ||||||||
SMSC地址类型 | 1 | 1 | 号码类型 | 号码表 | ||||||
SMSC号码 | N | 号码第2位 | 号码第1位 | |||||||
号码第4位 | 号码第3位 | |||||||||
…… | …… | |||||||||
号码第n位 | 号码第n-1位 | |||||||||
TPDU第一字节 | 1 | |||||||||
最长12字节 | 发送源号码长度 | 1 | 实际号码位数k(十六进制数) | |||||||
发送源号码类型 | 1 | 1 | 号码类型 | 号码表 | ||||||
发送源号码 | M | 号码第2位 | 号码第1位 | |||||||
号码第4位 | 号码第3位 | |||||||||
号码第k位 | 号码第k-1位 | |||||||||
TP-PID | 1 | |||||||||
TP-DCS | 1 | |||||||||
TP-SCTS | 7 | 年低位 | 年高位 | |||||||
月低位 | 月高位 | |||||||||
日低位 | 日高位 | |||||||||
时低位 | 时高位 | |||||||||
分低位 | 分高位 | |||||||||
秒低位 | 秒高位 | |||||||||
时 区 | ||||||||||
TP-UDL | 1 | |||||||||
最长140字节 | TP-UD短信息内容 | 1 | ||||||||
1 | ||||||||||
1 | ||||||||||
1 |
5.3 中文短信息的解码
由于中文字的编码是采用2个字节的编码,因此发送和接收中文或中英文混合的短信息只能采用PDU模式。但在GSM标准中,中文编码采用UTF-8的编码,不是目前国内常用的GB-2312编码,故还需要进行中文编码的转换,才能与采用GB-2313汉字库相配合显示汉字字型。
由于UTF-8和GB-2312编码之间不存在一一对应的线性关系,因此只能采用查表的方式进行转换。下面给出一个由UTF-8到GB-2312编码转换的算法。javascript:window.open(this.src);" style="cursor:pointer;"/>
① 建立UTF-8和GB-2312两个中文编码表,表中数据项为2个字节长度的十六进制的数,代表一个中文编码。两个表的长度分别为14 890字节(2×7445)。UTF-8编码表按数据项值从小到大排序,而在GB-2312编码表中,与UTF-8相同位置处为相同汉字的GB-2312码字,如图4所示。
② 软件解码过程为:每次从PDU模式SMS数据包的TP-UD中取出两个字节,采用二分法快速数据查找算法,在UTF-8编码表中找到其所在位置,然后在GB-2312表的相同位置处读取相对应的GB-2312编码。解码流程如图5所示。
③ 二分法的最坏查找次数为lg2(n+1),UTF-8表的长度n为7445,固最坏查找次数为13次,就是说一个中文编码由UTF-8到GB-2312的转换最多经过13次比较查找就可完成。 这比采用简单的顺序查表要快的多,大大减少了查表所花费的时间,非常适合在一般的嵌入式系统中使用。
④ 尽管两个汉字编码表要占用近30 KB(如还需要GB-2312到UTF-8的转换,则还要增加两个表,共占60 KB),但由于采用了ATmega128单片机,其片内有128KB的程序存储器,因此可将程序与表格放在一起。去掉60 KB的表格,仍有近70 KB的容量用于系统程序,因此完全不用外部扩充存储器(汉字字库除外),大大简化了硬件的结构和设计。
结 语
本文的设计方案已应用在我们研发的产品“车船载GPS-GSM卫星定位无线通信移动终端”上,经过多年的运行和使用,证明系统工作稳定可靠。2001年10月,在美国著名计算机应用杂志《CIRCUIT CELLAR》举办的世界性电子设计竞赛“Design Logic 2001 Contest”中,该产品获得三等奖。