Delphi实现串口编程收发短信

本文介绍如何使用Delphi通过串口操作手机实现短信的收发功能,包括PDU模式下的短信编码解码原理及实现方法,并提供GSM AT命令的使用指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分类: delphi 2008-03-28 15:21 890人阅读 评论(0) 收藏 举报

现 在网上有很多软件可以实现短信息服务,不外乎两种情况,一种是通过短信网关,比如新浪网,网易都提供这方面的服务,这种方法实现起来比较简单,所需资源较 少的,但是对于网站的依赖性太强,对网络的依赖同样无法避免,不适用于项目开发,而对于个人而言,有些短信网站收费不透明,会造成不必要的损失。另外一种 就是手机连电脑,通过串口操作手机收发短信。这是目前比较适合于小项目开发的一种方法,所需硬件包括一款手机,以及相应的数据线或是红外线适配器.该方法编码简单,只需对AT指令和串口编程比较熟悉就可以实现,而且对硬件需求不高。       

    本文讨论的是后者的方法, 通过这种方法收发短消息又分为三种模式:Block模式、Text模式和PDU模式。使用Block机生产厂家提供驱动支持,这种方法现在很少用了。Text Mode是纯文本方式,可使用不同的字符集,从技术上说也可用于发送中文短消息,但国内手机基本上不支持,主要用于欧美地区,也不在本文讨论范围之列。PDU串表面上是一串ASCII码,由‘0’-‘9’、 ‘A’-‘F’这些数字和字母组成。它们是8位字节的十六进制数,或者BCD码十进制数。PDU串不仅包含可显示的消息本身,还包含很多其它信息,如SMS服务中心号码、目标号码、回复号码、编码方式和服务时间等。

1.PDU编码解码

   在PDU Mode中,可以采用三种编码方式来对发送的内容进行编码,它们是7-bit、8-bit和UCS2编码。7-bit编码用于发送普通的ASCII字符,它将一串7-bit的字符(最高位为0)编码成8-bit的数据,每8个字符可“压缩”成7个;8-bit编码通常用于发送数据消息,比如图片和铃声等;而UCS2编码用于发送Unicode字符。PDU串的用户信息(TP-UD)段最大容量是140字节,所以在这三种编码方式下,可以发送的短消息的最大字符数分别是160、140和70。这里,将一个英文字母、一个汉字和一个数据字节都视为一个字符。

    需要注意的是,PDU串的用户信息长度(TP-UDL),在各种编码方式下意义有所不同。7-bit编码时,指原始短消息的字符个数,而不是编码后的字节数。8-bit编码时,就是字节数。UCS2编码时,也是字节数,等于原始短消息的字符数的两倍。

    下面介绍的内容,是在PDU Mode下发送和接收短消息的实现方法。发送和接收的PDU串,结构是不完全相同的。我们先用实际的例子说明PDU串的结构和编排方式。

(1) 发送信息的PDU串

中文:向手机13600554267发送中文“欢迎”两字,格式如下:   0011000B913106504562f7000810046B228FCE英文:向手机13600554267发送英文“hellohello”十字符,格式如下:

0011000B913106504562f70000AA0AE8329BFD4697D9EC37

    对以上的PDU串分析如下表:

 

分段

含义

说明

00

SMSC地址信息的长度

8613800250500,补‘F’凑成偶数个

11

基本参数(TP-MTI/VFP)

发送,TP-VP用相对格式

00

消息基准值(TP-MR)

0

0B

目标地址数字个数

共13个十进制数(不包括91和‘F’)

91

目标地址格式(TON/NPI)

用国际格式号码(在前面加‘+’)

3106504562f7

目标地址(TP-DA)

8613851872468,补‘F’凑成偶数个

00

协议标识(TP-PID)

是普通GSM类型,点到点方式

08

用户信息编码方式(TP-DCS)

UCS2编码(00:7-bit编码)

10

有效期(TP-VP)

短信的有效时间

04

用户信息长度(TP-UDL)

实际长度4个字节

6B228FCE

用户信息(TP-UD)

“欢迎”

以上内容是对中文信息的表示,需要注意的是“欢迎“两字,在实际长度计算的时候是4,而非2。因为UCS2编码时计算长度为原始短消息的字符数的两倍。而发送的”hellohello“英文短信,与其区别在于编码方式不同,以及长度计算有点差别,请自行分析。

(2)接受信息的PDU串

读取以上发送出来的短信,可以收到如下信息,接受到来自13600554267的“欢迎“PDU串为:0891683108503705F0040D91683106504562F7000830507001021500046B228FCE 。而接受到的“hellohello“PDU串为:

0891683108503705F0040D91683106504562F70000305070010201000AE8329BFD4697D9EC37。对以上的PDU串分析如下表:

含义

说明

08

SMSC地址信息的长度

共8个八位字节(包括91)

91

SMSC地址格式(TON/NPI)

用国际格式号码(在前面加‘+’)

683108503705F0

SMSC地址

8613800573500,补‘F’凑成偶数个

04

基本参数(TP-MTI/MMS/RP)

接收,无更多消息,有回复地址

0D

回复地址数字个数

共13个十进制数(不包括91和‘F’)

91

回复地址格式(TON/NPI)

用国际格式号码(在前面加‘+’)

683106504562F7

回复地址(TP-RA)

8613600554267,补‘F’凑成偶数个

00

协议标识(TP-PID)

是普通GSM类型,点到点方式

08

用户信息编码方式(TP-DCS)

UCS2编码(即中文)

30507001021500

时间戳(TP-SCTS)

2003-3-12 08:36:45  +8时区

04

用户信息长度(TP-UDL)

实际长度4个字节

6B228FCE

用户信息(TP-UD)

“欢迎!”

2.PDU的编码与解码

   (1)英文编码与解码

缺省的GSM字符集为7位编码,ASCII码为8位编码,编码就是将8位ASCII编码转换为7位编码。例如:1234 编码后得到31D98C06。将“1234”用二进制表示后,转为7位编码如下:

8位编码 00110001 00110010 00110011 00110100

7位编码 00110001 11011001 10001100 00000110

通过例子可以看出,将ascii8位编码的Bit8去掉,依次将下7位编码的后几位逐次移到前面,形成新的8位编码。解码是上面的逆向过程,就是将7位字符编码转换为8为字符编码。

   (2)中文编码与解码

中文编码较为简单,就是将GB2312的中文编码转换为Unicode编码即可。解码就是将Unicode编码转换为GB2312的中文编码即可。

在日常短信收发中,中文短信居多,而且,英文短信也可以作为中文短信来收发,如果,程序要求不高,所有短信均可使用中文编码。

3.常用GSM AT命令

串口连接手机实现短信收发须通过相应的GSM AT命令来实现的,用AT命令可以实现几乎所有功能,本文只介绍和短信收发相关的几条AT命令,相关命令如下表:

AT+CMGL

List SMS message from preferred store(列出SIM卡中的短消息PDU/text:   0/“REC UNREAD”-未读,1/“REC READ”-已读,2/“STO UNSENT”-待发,3/“STO SENT”-已发,4/“ALL”-全部的)

AT+CMGR

Read SMS message(读短消息)

AT+CMGS

Send SMS message(发送短消息)

AT+CMGD

Delete SMS message(删除SIM卡内存的短消息)

AT+CPMS

Preferred SMS message storage(选择短消息内存)

 

(1)使用方法

AT+CMGL为根据参数列出满足参数的所有短信,使用方法比较简单,只须在超级终端里面直接输入:AT+CMGL=X<ENTER>,X表示0、1、2、3、4等数字。<ENTER>为回车。

AT+CMGR为读取单条的短信,使用和AT+CMGL差不多,也是AT+CMGL=X<ENTER>,但是后面的X所表示的意义同,这里的X表示你所要读取的短信的索引号。经过测试,X的值也是有范围的,即从一开始到当前所选择的存储器的最大存储能力,如作者的西门子6618,在选择sim卡读取的时候,范围是:1-50;在选择sim卡读取的时候,范围是:1-25。如果超出以上范围,将返回error;如果不超出上面范围,但是读取的索引号没有相应短信,将返回:+CMGR: 0,,0。

AT+CMGS为发送短信的指令,使用方法稍微复杂一些。首先输入AT+CMGS=X<ENTER>,然后系统出现提示:>,即可输入你所要发送短信的PDU信息,最后以<CTRL>+Z结束。如向手机13600554267发送中文“欢迎”两字,格式如下其PDU串是: 0011000B913106504562f7000810046B228FCE,那么AT+CMGS=X处的X为18,计算方法是除掉最前面的“00“,余下的为36个字符,在除以2得18。

AT+CMGD为删除单条短信的指令,使用方法和AT+CMGR同,其X值也和AT+CMGR同意义。

AT+CPMS为选择短信存储位置的指令,AT+CPMS=ME为选择手机读取短信,AT+CPMS=SM为选择SIM卡读取。

4.串口连接手机测试

以西门子6618加数据线为例,本文所有设计到数据参数,均在西门子6618下测试通过。

(1)串口连接:用串口线连接手机与电脑串口,打开超级终端,选择相应的串口,将端口参数设置为:每秒位数(B)115200;数据位(D)8;奇偶校验(P)无;停止位(S)8;  数据流控制(F)硬件。

(2)连接测试

输入“AT”然后回车,屏幕上返回“OK”表明计算机与西门子6618已连接成功,西门子6618能够正常工作。这时就可以测试各类AT命令(如本文提到的各AT命令)。

5.程序实现

(1)启动delphi5,安装串口操作控件SPCOMM(具体下载以及安装此处不再详述,具体请查阅大富翁论坛http://www.delphibbs.com),添加相关控件如下图:

程序界面分为三大部分,最上面为连接手机时的参数设置;中间为at命令测试以及返回结果的显示,所有用到的at命令记录都存放于“历史记录”;下面为手机短信的收发与操作。

(2)代码

spcomm的操作,添加的spcomm的name属性设置为mycomm。mycomm的启动停止为:mycomm.StopComm,mycomm.StartComm。mycomm的启动代码如下:

try

    mycomm.StopComm;

    mycomm.StartComm;

  except

    Showmessage('串口打开失败!');

    Exit;

end;   

读写串口程序实现不难,无非是先向串口写入一串数据,然后根据串口返回的数据得到相应内容。写串口的指令可以用以下方式完成

sendstring:=AT指令+chr($0d)+chr($0a) ;

mycomm.WriteCommData(pchar(sendstring),Length(sendstring));

对于象发送短信AT+CMGS这样的特殊指令,完成一个完整指令,需要两次操作。

s:= 'at+cmgs='+长度+chr($0d)+chr($0a);

mycomm.WriteCommData(pchar(s),Length(s));

sleep(100);

s:=PDU信息+chr($1A);

mycomm.WriteCommData(pchar(s),Length(s));

具体短信内容转到PDU信息用到的编码函数chinese_code见下:(英文解码函数请自行分析编写)

function chinese_code(var s:WideString):String;

var i,len:Integer; cur:Integer; t:String;

begin

Result:='';

len:=Length(s);

i:=1;

while i<=len do

 begin

 cur:=ord(s[i]);

  //BCD转换

 FmtStr(t,'%4.4X',[cur]);

   Result:=Result+t;

     inc(i);

   end;

end;

读串口为在写入串口一定数据后,根据串口的数据返回读取。故我们可以在mycomm的onReceiveData事件时读取内容,代码如下:

f:=Tfilestream.Create(extractfilepath(application.exename)+'log.txt',fmopenwrite);

f.Seek(0,sofromend);

f.Write(buffer^,bufferlength);

f.Free;//将所有串口的数据写入log.txt作为历史记录

SetLength(S, BufferLength);

move(buffer^,pchar(s)^,bufferlength)  ;

result_memo.Lines.Add(s);

此处可以根据相应条件对串口返回的数据写入MEMO后做相应处理,AT+CMGL返回的数据可以用下面的DecodeChinese函数处理即可得到短信内容。DecodeChinese函数代码如下:(英文解码函数请自行分析编写)

function DecodeChinese(Inputstr:String):String;

var Buf:array[0..300] of widechar;

    i: Integer;

begin

  for i:= 0 to (Length(InputStr) div 4) - 1 do

  Buf[i] := WideChar(StrToInt('$'+Copy(InputStr,i*4+1,4)));

  Buf[i] := #0;

  Result := WideCharToString(Buf);

end;

6.广泛的应用

GSM在短信息方面的应用最具优势,具有永远在线、不需拨号、价格便宜、覆盖范围广等特点,特别适用于需频繁传送小流量数据的应用,如车辆调度、安全、导航、监控、监测等领域。对于一些企业来说,用来作为信息发布平台也是一种捷径。

DELPHI串口编程剖析 1 第一章 背景知识 3 1. 概述 3 2. 什么是接口? 3 3. 接口分类. 3 4. 为什么需要I/O接口? 3 5. I/O接口的功能 4 6. I/O接口的通信方式 5 7. I/O接口的分类 5 8. 串口的分类 8 9. 串口通信分类 11 10. 奇偶校验 12 第二章 串口通信编程简介 13 1. 串口的通信编程流程 13 2. Unix平台下对串口进行开发的方法 13 3. Windows平台下对串口进行开发的方法 13 第三章 使用DELPHI工具进行串口通信编程 15 第四章 串口编程的调试及其相关工具 27 串口通信编程剖析 第一章 背景知识 1. 概述 串口是计算机上I/O接口的一种,要掌握串口通信编程的相关知识,必须先了解I/O接口的相关知识。 I/O接口是接口的一种。 2. 什么是接口? 众所周知计算机是由CPU,存储器,外部终端设备组成. 接口就是用于CPU与外部设备、存储器的连接和数据交换的设备。 3. 接口分类. 广义的计算机接口有二种,见下表: 类別 用途 电路实现复杂性 存储器接口: 用于CPU与外部设备、存储器的连接 简单 I/O接口 数据交换 复杂 习惯上说到接口只是指I/O接口。本文沒作特別介绍的地方都叫I/O接口. 4. 为什么需要I/O接口? 计算机的外围设备品种繁多,几乎都采用了机电传动设备,因此,CPU在与I/O设备进行数据交换时存在以下问题: 速度不匹配: I/O设备的工作速度要比CPU慢许多,而且由于种类的不同,他们之间的速度差异也很大,例如硬盘的传输速度就要比打印机快出很多。 时序不匹配: 各个I/O设备都有自己的定时控制电路,以自己的速度传 输数据,无法与CPU的时序取得统一。 信息格式不匹配: 不同的I/O设备存储和处理信息的格式不同,例如可以分为串行和并行两种;也可以分为二进制格式、ACSII编和BCD编等。 信息类型不匹配: 不同I/O设备采用的信号类型不同,有些是数字信号,而有些是模拟信号,因此所采用的处理方式也不同。    基于以上原因,CPU与外设之间的数据交换必须通过I/O接口来完成。 5. I/O接口的功能 通常I/O接口有以下一些功能: 1)设置数据的寄存、缓冲逻辑,以适应CPU与外设之间的速度 差异,接口通常由一些寄存器或RAM芯片组成,如果芯片足够大还可以实现批量数据的传输; 2)能够进行信息格式的转换,例如串行和并行的转换; 3)能够协调CPU和外设两者在信息的类型和电平的差异,如电平 转换驱动器、数/模或模/数转换器等;    4)协调时序差异;    5)地址译和设备选择功能;    6)设置中断和DMA控制逻辑,以保证在中断和DMA允许的情况下产生中断和DMA请求信号,并在接受到中断和DMA应答之后完成中断处理和DMA传输。    6. I/O接口的通信方式 CPU通过接口对外设进行控制的方式有以下几种: 1)程序查询方式 这种方式下,CPU通过I/O指令询问指定外设当前的状态,如果外设 准备就绪,则进行数据的输入或输出,否则CPU等待,循环查询。 这种方式的优点是结构简单,只需要少量的硬件电路即可,缺点是由 于CPU的速度远远高于外设,因此通常处于等待状态,工作效率很 低。 2)中断处理方式 在这种方式下,CPU不再被动等待,而是可以执行其他程序,一旦 外设为数据交换准备就绪,可以向CPU提出服务请求,CPU如果响 应该请求,便暂时停止当前程序的执行,转去执行与该请求对应的 服务程序,完成后,再继续执行原来被中断的程序。   中断处理方式的优点是显而易见的,它不但为CPU省去了查询外设 状态和等待外设就绪所花费的时间,提高了CPU的工作效率,还满 足了外设的实时要求。但需要为每个I/O设备分配一个中断请求号 和相应的中断服务程序,此外还需要一个中断控制器(I/O接口芯 片)管理I/O设备提出的中断请求,例如设置中断屏蔽、中断请求 优先级等。此外,中断处理方式的缺点是每传送一个字符都要进行 中断,启动中断控制器,还要保留和恢复现场以便能继续原程序的 执行,花费的工作量很大,这样如果需要大量数据交换,系统的性 能会很低。 3)DMA(直接存储器存取)传送方式 DMA最明显的一个特点是它不是用软件而是采用一个专门的控制 器来控制内存与外设之间的数据交流,无须CPU介入,大大提高 CPU的工作效率。   在进行DMA数据传送之前,DMA控制器会向CPU申请总线控 制 权,CPU如果允许,则将控制权交出,因此,在数据交换时, 总线控制权由DMA控制器掌握,在传输结束后,DMA控制器将 总线控制权交还给CPU。    7. I/O接口的分类 7.1. 并行接口   目前,计算机中的并行接口主要作为打印机端口,接口使用的不再是36针接头而是25针D形接头。所谓“并行”,是指8位数据同时通过并行线进行传送,这样数据传送速度大大提高,但并行传送的线路长度受到限制,因为长度增加,干扰就会增加,容易出错。   现在有五种常见的并口:4位、8位、半8位、EPP和ECP,大多数PC机配有4位或8位的并口,许多利用Intel386芯片组的便携机配有EPP口,支持全部IEEE1284并口规格的计算机配有ECP并口。   标准并行口4位、8位、半8位:   4位口一次只能输入4位数据,但可以输出8位数据;8位口可以一次输入和输出8位数据;半8位也可以。   EPP口(增强并行口):由Intel等公司开发,允许8位双向数据传送,可以连接各种非打印机设备,如扫描仪、LAN适配器、磁盘驱动器和CDROM 驱动器等。   ECP口(扩展并行口):由Microsoft、HP公司开发,能支持命令周期、数据周期和多个逻辑设备寻址,在多任务环境下可以使用DMA(直接存储器 访问)。   目前几乎所有的586机的主板都集成了并行口插座,标注为 Paralle1或LPT1,是一个26针的双排针插座。 7.2. 串行接口   计算机的另一种标准接口是串行口,现在的PC机一般至少有两个串行口COM1和COM2。串行口不同于并行口之处在于它的数据和控制信息是一位接一位串行地传送下去。这样,虽然速度会慢一些,但传送距离较并行口更长,因此长距离的通信应使用串行口。通常COM1使用的是9针D形连接器,而COM2有些使 用的是老式的DB25针连接器。    7.3. 磁盘接口 1)IDE接口   IDE接口也叫做ATA端口,只可以接两个容量不超过528M的硬盘驱动器,接口的成本很低,因此在386、486时期非常流行。但大多数IDE接口不支持DMA数据传送,只能使用标准的PCI/O端口指令来传送所有的命令、状态、数据。几乎所有的586主板上都集成了两个40针的双排针IDE接口插座,分别标注为IDE1和IDE2。 2)EIDE接口 EIDE接口较IDE接口有了很大改进,是目前最流行的接口。 首先,它所支持的外设不再是2个而是4个了,所支持的设备除了硬盘,还包括CD-ROM驱动器磁盘备份设备等。   其次,EIDE标准取消了528MB的限制,代之以8GP限制。   第三,EIDE有更高的数据传送速率,支持PIO模式3和模式4标准。    7.4. SCSI接口   SCSI(SmallComputerSystemInterface)小计算机系统接口,在做图形处理和网络服务的计算机中被广泛采用SCSI接口的硬盘。除了硬盘以外,SCSI接口还可以连接CD-ROM驱动器、扫描仪和打印机等,它具有以下特点:   *可同时连接7个外设;   *总线配置为并行8位、16位或32位;   *允许最大硬盘空间为8.4GB(有些已达到9.09GB);   *更高的数据传输速率,IDE是2MB每秒,SCSI通常可以达到5MB每秒,FASTSCSI(SCSI-2)能达到10MB每秒,最新的SCSI-3甚至能够达到40MB每秒,而EIDE最高只能达到16.6MB每秒;   *成本较IDE和EIDE接口高很多,而且,SCSI接口硬盘必须和SCSI接口卡配合使用,SCSI接口卡也比IED和EIDE接口贵很多。   *SCSI接口是智能化的,可以彼此通信而不增加CPU的负担。在IDE和EIDE设备之间传输数据时,CPU必须介入,而SCSI设备在数据传输过程中起主动作用,并能在SCSI总线内部具体执行,直至完成再通知CPU。   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值