gsm数字蜂窝移动通信技术已得到成熟而广泛的应用,目前以建成的覆盖全国的gsm数字蜂窝移动通信网,是我国公众移动通信网的重要方式。它能提供话音、短消息、数据等多种业务。短消息服务是gsm网络的一项重要业务,在远距离监控、数据采集、gps定位、无线报警、缴费通知、车辆调度等领域有着广泛的应用。
gsm模块通常都提供uart串行接口,因此很容易和单片机在物理层上互联。使用符合gsm07.05和gsm07.07标准的at指令集,可以使gsm模块方便地完成短消息接收/发送等各种操作。其通信框图如图1所示。
移动设备me主要负责与gsm网络进行无线通信,终端适配器ta负责me与外部终端设备te的信息交换,at指令就是在ta与te之间传送的。te可以是pc,或者是单片机系统,通过at指令与me进行信息交互。现在市场上的gsm模块,如tc35、falcom等,都把me和ta集成在一起,这样整个通信就变成了te与gsm模块之间的通信了。
一般地,gsm模块在处理短消息时,采用一问一答的信息交互方式,这比较符合at指令集的精神。但在实际应用中,发现这种方法存在一定的缺点:模块接收到短消息并存储起来,用户再用查询方式,发送指令“at+cmgl”或“at+cmgr”,使短消息传送到te,这中间会有一定的延时。另外,由于sim卡容量有限,要保证短消息及时准备地接收,还要经常删除sim卡中的短消息,这样多次的读写操作,势必会影响sim卡的寿命。因此,有必要进行一些软件设置,使短消息不通过sim卡,而直接发送至终端设备。本文给出一种在嵌入式系统中实时处理短消息的实现方法,当移动设备gsm模块接收到短消息时,直接将消息转发到终端设备,提高系统的响应速度和处理效率。
1 硬件接口实现
一般,gsm无线通信控制终端采用标准的gsm模块进行二次开发,目前市场上很多,如tc35、falcom、wismo3等。它们都具备gsm无线通信的全部功能,支持gsm07.05,gsm07.07所定义的at指令集。
在本设计中,采用的gsm通信模块为falcomc2d,单片机使用的是atmel公司的高速8位处理器atmega128。atmega128内部集成有4kb的ram,4kb的eeprom,128kb的flash,以及2个uart串行接口等。其高速和大容量ram的特性,为处理短消息这样的大数据包提供了便利;同时,节省了外围器件,使得硬件结构简化,提高系统可靠性。中文液晶屏用来显示接收到的中英文短信。系统的硬件接口框图如图2所示。
2 系统参数设置
短消息的发送和接收控制模式有三种:block模式、pdu模式和text模式。使用block模式需要手机生产厂家提供驱动支持。目前,pdu模式已取代block模式,而text模式不支持中文。因此,为了系统的通用性,兼容中英文短消息的发送接收,本系统使用pdu模式来处理短消息。
在进行系统设置前,先简要说明一下短消息类(class)的概念:根据指定存储的位置,短消息分为class0-3四个类,也可以不指定类别(no class),由移动设备按默认设置进行处理,存储到内存或者sim卡中。在tpdu的tp-dcs字节中,当bit7-bit4为00x1、1111时,bit1-bit0指示消息所属类。
00——class 0,可直接显示。
01——class 1,默认储存在me内存中。
02——class 2,储存在sim卡中。
03——class 3,可直接传输到终端设备te。
默认的短消息存在sim卡中,无类别的短消息通常也存在sim卡中。
gsm modem一般都支持一条“at+cnmi”指令,用于设定当有某类短消息到达时,如何处理它——只储存在制定的内存(易失的/非易失的)中;先储存后通知te;直接转发到te,等等。
“at+cnmi”指令语法为:
at+cnmi=<mode>,<mt>,<bm>,<ds>,<bfr>
(1)<mode>控制通知te的方式。
0——先将通知缓存起来,再按照<mt>的值进行发送。
1——在数据线空闲的情况下,通知te,否则,不通知te。
2——数据线空闲时,直接通知te;否则先将通知缓存起来,待数据线空闲时再行发送。
3——直接通知te。在数据线被占用的情况下,通知te的消息将混合在数据中一起传输。
(2)<mt>设置短消息存储和通知te的内容。
0——接受的短消息存储到默认的内存位置(包括class 3),不通知te。
1——接收的短消息储存到默认的内存位置,并且向te发出通知(包括class 3)。通知的形式为:
+cmti:”sm”,<index>
2——对于class 2短消息,储存到sim卡,并且向te发出通知;对于其他class,直接将短消息转发到te:
+cmt:[<alpha>],<length><cr><lf><pdu>(pdu模式)
或者+cmt:<oa>,[<alpha>,]<scts>[,<tooa>,<fo>,<pid>,<dcs>,<sca>,<tosca>,<length>]<cr><lf><data>(text模式)
3——对于class 3短消息,直接转发到te,同<mt>=2;对于其他class,同<mt>=1。
(3)bm、ds、bfr的含义,请参考相关标准文档。一般不需要去关心它们,设置为0即可。
综合以上分析,若使短消息不经过sim卡,直接发送至te,可以设置:
at+cnmi=2,2,0,0,0
但是这样还有一个问题,class 2的短信,还是会存入sim卡中,并发送+cmti:”sm”,<index>。那么,接收程序需要处理短信通知和内容两种情况,增加了复杂性。如果发送方也由程序控制,可以只发no class和class 1的短信。这里选用no class的配置。pdu模式下,令tp-dcs的bit7-bit4为00x0,即可设置发送的短信为no class。通常用手机发送的短信,也是无类别的。
通信时,发送接收双方要统一短信格式。在发送方设置at+cmgf=0,确定短信发送格式为pdu方式。
在接收方设置:
at+cmgf=0 //短信接收格式为pdu方式
at+csms=0
如果at+csms=1,接收到短信时,te需在一定的时间内发送反馈消息至模块;若超时,<mode>和<mt>的值会强制复位到0。那么,再有新的短信将不能被正确处理,需要用“at+cnmi”指令重新设置参数才行。这增加了程序处理的复杂性。at+csms=0时,省去了这些麻烦。
3 pdu模式下的中英文通信接收实现
系统参数设置好以后,当接收到新的短信时,gsm模块直接转发至te的格式如下所示:
+cmt:,23
0891683108200105f0040ba13119388742f5000850802251739120044f60597d
“+cmt:”为短消息指示标识,由at+cnmi的值确定。“23”指明该短消息pdu数据包长度为23字节。第2行为十六进制数据,总长度为32字节,其中smsc地址占用9字节,其余23字节为tpdu数据。
需要指出的是,和at指令中的指令符号、数字一样,pdu数据都是以ascii编码的形式传送的,比如“a”的ascii编码为41h,“0”的ascii编码为30h等。pdu数据包的内容是以十六进制表示的数据,但并不是直接向单片机传递十六进制数据,而是把每一位十六进制数以ascii编码来发送。例如:08h会以30h(“0”),38h(“8”)的形式发送。这样,1个字节的十六进制数就变成2个字节的ascii码。但是,pdu数据包中的数据字节长度部分仍然是原始十六进制字节的长度,而不是变成ascii码的字节长度,这在编程时应特别注意,否则,接收和处理数据就会不完整。单片机接收到pdu数据包数据后,必须将其恢复成十六进制数据,其算法如下:
设a为接收的ascii码,b为转换后的十六进制数。如果a<39h,则b=a-30h;如果a>39h,则b=a-30h-07h,最后把前后2个数合并为1个字节。
pdu数据包有着严格的定义,现简单介绍如下:
pdu的这种格式,层次清楚,结构清晰,方便接收。在本系统中,采用usart中断方式接收短信,充分利用了avr系列单片机指令执行速度块的特点,并在接收过程中运用状态机的思想,解析出短信中的发送源号码、日期时间、数据编码方案和用户短信数据。接收到一个完整的pdu数据包后,中断程序中设置接收完成标志为1。在主程序中,检测到接收完成标志为1时,就根据数据编码方案,对接收到的短信解码并保存,并准备下一条段短信的接收。如果短信到来时ta与te的数据线忙,则短信会暂时保存在ta的缓存中,等数据线空闲时再转发至te。
在pdu模式中,发送普通的ascii字符用7-bit编码方式,将一串7-bit字符编码为8-bit数据,每8个字符可压缩成7个。如果发送中文字符,则采用ucs2编码方式,每个中文字符用16位的unicode字符表示;如果是中英文混合的短信,由于英文字符只占1字节,需要补0,成为16位的编码。例如,“你好!”的unicode编码为4f60597d0021,其中“!”的ascii码为21h,编码后为0021h。pdu的用户数据段最大容量是140字节,gsm模块发送给单片机的是280个ascii编码。除此之外,还要接收保存发送源号码、日期和时间等信息。由于atmega128有4kb内部sram,为短信的接收和解码提供了足够的空间。这是它的一大优势。pdu串的用户信息长度tpudl,在7-bit编码时,指原始短消息的字符个数,而不是编码后的字节数;在ucs2编码时,指编码后的十六进制字节数,因为1个字符用2个字节表示,所以经ucs2编码后,字节数等于原始短消息字符数的2倍。
pdu模式下可以发送中英文短信,但是对英文字符和数字的7-bit编码/解码比较复杂,如果只需要发送和接收纯英文字符和数字字符,最好采用text方式。
3.1 7-bit用户数据解码
7-bit数据解码时,将源数据每7个字节分为一组,解码成8个字符。基本自然是:将第n个字节左移n位,再加上前一字节的剩余数据,即第(n-1)个字节右移(8-n)位的数值,屏幕最高位,即得到一目标字符数据,n=0…6。第7个字节右移1位就得到解码后的第8个字符数据。
3.2 中文字符解码
短消息的中文字符采用unicode 编码,占用2字节,不是目前国内常用的gb-2312编码,为了能够在带有gb-2312汉字库的液晶上显示,还需要进行中文编码的转换。
基本思想就是建立unicode和gb-2312两个中文编码表,通过查找实现相互转换。具体过程这里不再叙述。请参考文献[1]。
结语
上述介绍的在嵌入式系统中,实时接收处理短消息的设计方案,已在车载gsm-gps系统上应用。经过长时间的操作使用,系统工作稳定,用户反映良好。