新闻  |   论坛  |   博客  |   在线研讨会
GSM短消息收发模块与AT89C55单片机通信程序的设计与实现
dawning642 | 2007-08-09 11:33:55    阅读:5381   发布文章

 
GSM短消息收发模块与AT89C55单片机通信程序的设计与实现
 
 
       摘要:本文首先介绍了GSM移动通信中的收发短消息(SMS)协议及其编码方式,接着分别探讨了AT89C55微处理器与Motorola D15短消息模块发送、接收接口子程序的设计,并给出了详细的MCS-51编码程序。
关键词:SMS编码;GSM; AT89C55;Motorola D15
 
1.0 引言
GSM(Global System for Mobile communication)系统是目前基于时分多址技术的移动通讯体制中比较成熟、完善、应用较广泛的一种系统,主要提供话音、短信息、数据等多种业务。基于GSM短消息功能可以做成传输各种检测、监控数据信号和控制命令的数据通信系统,无需另外组建专用通信网络,被广泛用于远程监控、定位导航、个人通信终端等场合。
Motorola D15是带语音,数据,传真和短消息支持的PHASE II GSM四类嵌入式封装的模块,常应用于导航,紧急服务,安全系统等领域。数据应用能提供包括车载信息,移动计算,资产管理,远程咪表读取,街灯控制,家庭安全,销售管理,法事管理,POS连接,家用器具监视和控制,显示系统,装入管理等功能。
本文以Motorola D15模块为例,探讨了AT89C55微处理器与Motorola D15短消息模块发送、接收接口子程序的具体实现过程。
1.1 SMS协议及其编码方式
GSM移动通信中的短消息传输主要有以下3种类型:①分组模式(Block Mode)。该模式是最早期的短消息传输方式,其通信效率最低。②文本模式(Text Mode)。Motorola D15不支持该模式。③PDU(Protocol Date Unit)模式(PDU模式)。该模式是当前短消息协议中被广泛使用的模式。
       欧洲ETS(Electronic Telegraph System电报系统)协会规定:通过GSM数字蜂窝移动通信网络来发送短消息,用户数据必须转化为GSM字符。而且,用户数据的内容必须是ASCII码字符集里的0x00到0x7f,7位编码的字符(这是对于英文短消息的规定)。因此,用户数据的7位数据,必须转化为8位的GSM字符。其中,每个短消息的信息量限制为140个八位组(7比特编码,160个字符)。以下着重介绍一下如何把7位的ASCII码内容编码为8位的GSM内容。
       假设用户要发送一条内容为“ABCDE”的短消息。查阅ASCII字符集可知,它们的编码分别是:0x41、0x42、0x43、0x44、0x45,其对应的二进制数分别是:01000001、01000010、01000011、01000100、01000101。接着可通过逐个增加位数的移位方式来使7位的用户码变为8位的GSM码,如图1所示。    

    图1  ASCII码编码为GSM码示例

       注意以上编码方式是以每8个ASCII码字符为一组的,没有达到8个一组的话,最后一个字符移位后高位填充0,依此循环而形成8位一组的编码。经过以上的编码变换后,7位的ASCII码字符就变成了8位的GSM字符,其编码结果分别为0x41、 0xE1、0x90、0x58、0x04。如果160个ASCII字符经过这种编码变换后,则会转化为140个GSM字符内容。
       对于所接收到的短消息是发送短消息的反编码,即把接收到的8位二进制的GSM字符重新译码为7位的ASCII码字符。例如,用户接收到6个GSM字符的十六进制的内容如下:
 
图2  GSM码译码为ASCII码示例
 
经过译码后,用户接收到的内容为“ROHDE ”。
       在解码接收到的短消息时,以7个GSM字符为一组的,不足一组的最后一个字符移位后剩余的高位填充0。
1.2 短消息收发程序的实现
1.2.1 短消息接收子程序
通过Motorola D15接收到的短消息在89C55微处理器内存中存储形式是把每条消息中的每个字母的ASCII码的内容拆分后的ASCII码形式存储于内存中。例如,假设用户接收到的GSM字符为AB,字符“A”的ASCII码为41,其中,将“41”拆分后的4的ASCII码为34、1的ASCII码为31。因此在89C55微处理器内存中存储的内容是3431。同理可知,字符“B”在89C55微处理器内存中的存储形式是3432。可见,字符“AB”在89C55微处理中存储的内容是34313432。
在进行对所接收到的内容进行译码时,则需先把两个字节的字符转化成一个字节的内容,其对应的子程序命名为ASCIIToHEX。由于ASCII码的编码范围为0x00到0x7F,其中数字“0~9”是以3为ASCII码的高位,字母“A~Z”是以4为ASCII码的高位,因此,区分数字“0~9”和字母“A~Z”的方法只需判断ASCII码的高位即可。若ASCII码的高位为3,则只保留ASCII码的低位;若ASCII码的高位为4,只需屏蔽ASCII码的高位,保留ASCII码的低位且进行加9的运算。ASCIIToHEX子程序编码如下。
AtC0:  ANL     A, #4FH
           JNB     ACC.6, AtC3
           CLR     Acc.6
           SETB    Acc.3
           INC     A
AtC3:  JNB     f0, AtC4
           CLR     f0
           SWAP    A
           XCH     A, B
           SJMP    AtC0
AtC4:   ORL     A, B
            RET
程序说明:算法:A+B=AB(注:此处A、B为A字符,B字符,非寄存器),把A表述的ASCII转化成字符和B表述的ASCII转化成字符合并为一个字符(十六进制)。     数字0(30)到9(39)与4Fh相与,保留低位。
字母A到F与4Fh相与,内容不变,仍为41,42,43,44,45,46。因此,
0100 0001 -> 0000 1001 -> 0000 1010 把第6位移位到第3位后(+1)
0100 0001 -> 0000 1001 -> 0000 1010 把第6位移位到第3位后(+1)
0100 0010 -> 0000 1010 -> 0000 1011 把第6位移位到第3位后(+1)
0100 0011 -> 0000 1011 -> 0000 1100 把第6位移位到第3位后(+1)
0100 0100 -> 0000 1100 -> 0000 1101 把第6位移位到第3位后(+1)
0100 0101 -> 0000 1101 -> 0000 1110 把第6位移位到第3位后(+1)
0100 0110 -> 0000 1110 -> 0000 1111 把第6位移位到第3位后(+1)
短消息接收子程序编码如下。
 MOV      DPTR, #Addr_SMSBuf-1   ;Addr_SMSBuf为接收短消息的缓冲区
 MOV      R7,DPH
 MOV      R6,DPL
 MOV      DPTR, #Addr_SMStmpBuf
 MOV      R3,DPH
 MOV      R2,DPL
AStS0:   MOV      DPH,R7
 MOV      DPL,R6
 INC       DPTR
 MOVX    A,@DPTR           ;接收的ASCII码字符以0Ah,0Dh结尾
 CJNE      A,#0AH,AStS1       ;仅对0Ah作判断
 CLR       A                          ;最后以00h为结尾
MOV      DPH,R3               
MOV      DPL,R2                          
MOVX     @DPTR,A                 ;反ASCII码结果存储
INC      DPTR
 MOVX     @DPTR,A
SJMP     SMSDecode          ;跳到译码模块
AStS1: XCH      A, B            ;暂存一个字符
INC      DPTR
MOV      R7, DPH
MOV      R6, DPL
MOVX     A, @DPTR                          ;调出两个字符
XCH       A, B                           
LCALL    ASCIItoHEX                ;调用两个字节合并为一个字节反ASCII子程序
MOV      DPH, R3
MOV      DPL, R2
MOVX     @DPTR, A                          ;结果存储
INC       DPTR
MOV      R3, DPH
MOV      R2, DPL
SJMP      AStS0
通过Motorola D15接收到的短消息在89C55微处理器内存中是以0DH、0AH结尾的。由于以上程序的处理结果仍是GSM字符,因此还需把GSM字符译成ASCII码字符,使它变成用户易于理解、方便阅读的内容。译码工作就是把GSM字符的十六进制转化成二进制后,把二进制的高位从1位到7位,逐个增加位数移位,把高位变成低位,不够的填充0即可。对此,只需应用移位指令即可。译码子程序编码如下。
MOV     DPTR, #Addr_SMStmpBuf   ;指向短消息工作缓冲区首地址
MOV     R7,DPH
MOV     R6,DPL
MOV     DPTR, #Addr_SMSBuf         ;指向接收短消息译码的结果缓冲区首地址
MOV     R3, DPH
MOV     R2, DPL
SMSDe0:  
MOV     R5, #01H               ;移位计数器
MOV     B, #0H
MOV     DPH, R7
MOV     DPL, R6                ;指向工作缓冲区的一个字节
MOVX    A,@DPTR               ;读取一个字节
INC      DPTR                  ;接收缓冲区指针后移
MOV     R7, DPH
MOV     R6, DPL
MOV     C, ACC.7               ; C保存第一个字节的高位
CLR     ACC.7
MOV     DPH,R3
MOV     DPL,R2
MOVX    @DPTR,A      ;移位的数据保存在译码/编码缓冲区(Addr_SMSBuf)
INC      DPTR          ;译码/编码缓冲区指针后移
MOV     R3, DPH
MOV     R2, DPL
CLR     A
RLC     A
MOV     R1, A           ; R1保存高位移到低位的结果
SMSDe00: 
MOV     DPH, R7
MOV     DPL, R6
MOVX    A, @DPTR
JZ        SMSDeCodeExit
INC      R5              ;移位次数加一
CJNE     R5, #08H,SMSDe1
MOV     A, R1
MOV     DPH, R3
MOV     DPL,R2
MOVX    @DPTR,A
INC      DPTR
MOV     R3, DPH
MOV     R2, DPL
LJMP    SMSDe0
SMSDe1:  
MOV     A, R5
MOV     R4, A
MOV     B, #0H
SMSDe2:  
MOVX    A, @DPTR
CLR      C
RLC      A
MOVX    @DPTR, A
MOV     A,B
RLC      A
MOV     B, A
DJNZ     R4, SMSDe2             ;左移n次
CLR      C                        ;右移1次
MOVX    A, @DPTR
RRC      A
ORL      A, R1
MOV    R1, B        ;保存当前移位的结果,下一次使用,R1的内容不能动
INC      DPTR                  ;
MOV     R7, DPH
MOV     R6, DPL
MOV     DPH, R3
MOV     DPL, R2
MOVX    @DPTR, A               ;保存移位或的结果
INC      DPTR
MOV     R3, DPH
MOV     R2, DPL
LJMP    SMSDe00
SMSDeCodeExit:
MOV     DPH, R3                ;译码结果以00h结束
MOV     DPL, R2
MOVX    @DPTR, A
RET
1.2.2 发送短消息编码子程序
短消息发送的格式与短消息接收格式不同之处在于,它是把7位ASCII码字符转化成8位的GSM字符,且把7位的ASCII字符逐个增加移动低位位数变成高位的方法来实现编码的。因此可以采用循环移位的方式来完成具体的编码。短消息发送子程序编码如下。
MOV    gSMSLength,#0h            ;默认短消息长度为1。
MOV    DPTR,#Addr_SMSBuf     ;指向短消息发送/接收缓冲区
MOV    R7,DPH
MOV    R6,DPL
MOV    DPTR,#Addr_SMStmpBuf      ;指向工作缓冲区
MOV    R3,DPH
MOV    R2,DPL
MOV    R5,#01H                   ;循环次数,编码要求
SMSE0:       
INC    gSMSLength                ;短消息字节数加一
MOV    DPH,R7                    ;
MOV   DPL,R6
MOVX   A,@DPTR
MOV    R1,A                      ;入口参数
INC    DPTR                      ;入口参数,指向两个字节的高地址
MOV    R7,DPH
MOV    R6,DPL
MOVX   A,@DPTR                 ;判断是否结束(00h)
JZ     SMSExit                    ;编码模块出口处
MOV    A,R5                      ; R5 为一个字节移位的位数
MOV    R4,A                      ; R4 在Shift 模块中作为循环移位控制
以下为Shift模块,该模块的功能是把两个连续的字节进行移位n次(R3->R1)。程序如下。
Shift:        MOV    B,#0
Shift0:       MOV    DPH,R7
        MOV    DPL,R6
    MOVX   A,@DPTR       ;相当于R3保存两个字节中的高字节              CLR    C
        RRC    A
        MOVX   @DPTR,A
        MOV    A,B
        RRC    A
        MOV    B,A
        DJNZ   R4,Shift0
        ORL    A,R1           ; A 保存的是低字节,被移位后的结果(来自高字节的低n位)
        MOV    B,#01H         ;入口参数,后移的字节数
      LCALL DPTRBack           ;调用指针后移子程序,A不受影响
      MOVX   @DPTR,A            ;保存回到原来的地址
      INC    DPTR
      MOV    R7,DPH
      MOV    R6,DPL     
      MOV    DPH,R3            
      MOV    DPL,R2           
      MOVX @DPTR,A     ;运行到此,移位完成一个字节,将此字节保存到译码/编码缓冲区
      INC    DPTR              
      MOV    R3,DPH
      MOV    R2,DPL
      MOV    DPH,R7            
      MOV    DPL,R6            
      MOV    B,#01H            
      LCALL DPTRBack          
      CLR    A                  ;完成一个字节后,该字节的内容清零
      MOVX   @DPTR,A          ;接收和发送缓冲区清零
      INC    R5
      CJNE R5,#08H,SMSE0     
      INC    gSMSLength         ;短消息字节数加一
      MOV    R5,#01H           ;运行到此空出一个节
      MOV    DPH,R7           
      MOV    DPL,R6
      INC    DPTR
      MOV    R7,DPH
      MOV    R6,DPL
      SJMP   SMSE0
SMSExit:     
MOV    DPH,R3             ;程序编码完毕,退出
      MOV    DPL,R2             ;
      MOV    A,R1               ;把最后一个字节的内宾保存在译码/编码
     MOVX   @DPTR,A            ;缓冲区
     CLR    A               ;最后以00h结尾
     INC    DPTR        ;此格式为下面的StrToASCIIStr模块结束判断标志
     MOVX   @DPTR,A
以下为StrToASCIIStr模块,该模块主要功能是实现把一串字符串转换成ASCII串,1
个字节扩展成2个字节。之所以要这样做,是因为51芯片存储的内容发送到Motorola D15所决定的。程序如下:
      MOV    DPTR,#Addr_SMStmpBuf     ;指向将要ASCII码化的字符串首地址
      MOV    R7,DPH
      MOV    R6,DPL
      MOV    DPTR,#Addr_SMSBuf       ;指向发送/接收短消息缓冲区
      MOV    R3,DPH
      MOV    R2,DPL
StAS0: MOV    DPH,R7
      MOV    DPL,R6
      MOVX   A,@DPTR
      JZ     StAS1
      INC    DPTR
      MOV    R7,DPH
      MOV    R6,DPL
      LCALL HEXtoASCII                                 ;调用十六进制转换为ASCII字符的子程序,即把一个字节转换成2个字节
      MOV    DPH,R3
      MOV    DPL,R2
      MOVX   @DPTR,A
      INC    DPTR
      MOV    A,B
      MOVX   @DPTR,A
      INC    DPTR
      MOV    R3,DPH
      MOV    R2,DPL
      SJMP   StAS0
StAS1: MOV    DPH,R3
      MOV    DPL,R2            
      MOV    A,#1AH             ;1A-0D 表示发送内容结束,此格式为D15模块发送短消息的格式要求
      MOVX   @DPTR,A          
      INC     DPTR              
      MOV    A,#0DH             
     MOVX   @DPTR,A
      RET
(未完,待续)

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客