1、用串口连接GSM手机发送和接收短消息 我们打算开发一个基于短消息方式地系统,如何利用进行数据通信? 首先,我们要对由制订地规范有所了解.与我们讨论地短消息收发有关地规范主要包括 、 和 .前二者着重描述地技术实现(含编码方式),后者则规定了地接口标准(命令集).文档收集自网络,仅用于个人学习一共有三种方式来发送和接收信息: , 和 . 已是昔日黄花,目前很少用了. 是纯文本方式,可使用不同地字符集,从技术上说也可用于发送中文短消息,但国内手机基本上不支持,主要用于欧美地区. 被所有手机支持,可以使用任何字符集,这也是手机默认地编码方式. 比较简单,而且不适合做自定义数据传输,我们就不讨论了.下
2、面介绍地内容,是在 下发送和接收短消息地实现方法.文档收集自网络,仅用于个人学习串表面上是一串码,由、 这些数字和字母组成.它们是位字节地十六进制数,或者码十进制数.串不仅包含可显示地消息本身,还包含很多其它信息,如服务中心号码、目标号码、回复号码、编码方式和服务时间等.发送和接收地串,结构是不完全相同地.我们先用两个实际地例子说明串地结构和编排方式.文档收集自网络,仅用于个人学习例 发送:号码是,对方号码是,消息内容是“!”.从手机发出地串可以是文档收集自网络,仅用于个人学习 文档收集自网络,仅用于个人学习对照规范,具体分析:分段 含义 说明 地址信息地长度 共个八位字节(包括) 地址格式(
3、) 用国际格式号码(在前面加) 地址 ,补凑成偶数个 文档收集自网络,仅用于个人学习 基本参数() 发送,用相对格式 消息基准值() 目标地址数字个数 共个十进制数(不包括和) 目标地址格式() 用国际格式号码(在前面加) 目标地址() ,补凑成偶数个 文档收集自网络,仅用于个人学习 协议标识() 是普通类型,点到点方式 用户信息编码方式() 编码 有效期() 分钟 用户信息长度() 实际长度个字节 用户信息() “!” 例 接收:号码是,对方号码是,消息内容是“你好!”.手机接收到地串可以是文档收集自网络,仅用于个人学习 文档收集自网络,仅用于个人学习对照规范,具体分析:分段 含义 说明 地
4、址信息地长度 个八位字节(包括) 地址格式() 用国际格式号码(在前面加) 地址 ,补凑成偶数个 文档收集自网络,仅用于个人学习 基本参数() 接收,无更多消息,有回复地址 回复地址数字个数 共个十进制数(不包括和) 回复地址格式() 用国际格式号码(在前面加) 回复地址() ,补凑成偶数个 文档收集自网络,仅用于个人学习 协议标识() 是普通类型,点到点方式 用户信息编码方式() 编码 时间戳() 时区 文档收集自网络,仅用于个人学习 用户信息长度() 实际长度个字节 用户信息() “你好!” 若基本参数地最高位()为,则没有回复地址地三个段.从上发出地短消息常常是这种情形.文档收集自网络,
5、仅用于个人学习注意号码和时间地表示方法,不是按正常顺序顺着来地,而且要以将奇数补成偶数. 上面两例中已经出现了和编码,请详细介绍一下这些编码方式? 在 中,可以采用三种编码方式来对发送地内容进行编码,它们是、和编码.编码用于发送普通地字符,它将一串地字符(最高位为)编码成地数据,每个字符可“压缩”成个;编码通常用于发送数据消息,比如图片和铃声等;而编码用于发送字符.串地用户信息()段最大容量是字节,所以在这三种编码方式下,可以发送地短消息地最大字符数分别是、和.这里,将一个英文字母、一个汉字和一个数据字节都视为一个字符.文档收集自网络,仅用于个人学习需要注意地是,串地用户信息长度(),在各种编
6、码方式下意义有所不同.编码时,指原始短消息地字符个数,而不是编码后地字节数.编码时,就是字节数.编码时,也是字节数,等于原始短消息地字符数地两倍.如果用户信息()中存在一个头(基本参数地为),在所有编码方式下,用户信息长度()都等于头长度与编码后字节数之和.如果采用 所建议地压缩算法(地高位为),则该长度也是压缩编码后字节数或头长度与压缩编码后字节数之和.文档收集自网络,仅用于个人学习下面以一个具体地例子说明编码地过程.我们对英文短信“!”进行编码:将源串每个字符分为一组(这个例子中不满个)进行编码,在组内字符间压缩,但每组之间是没有什么联系地.文档收集自网络,仅用于个人学习用实现编码和解码地
7、算法如下: 编码 : 源字符串指针 : 目标编码串指针 : 源字符串长度 返回: 目标编码串长度 ( * , * , )文档收集自网络,仅用于个人学习 ; 源字符串地计数值 ; 目标编码串地计数值 ; 当前正在处理地组内字符字节地序号,范围是 ; 上一字节残余地数据 计数值初始化 ; ; 将源串每个字节分为一组,压缩成个字节 循环该处理过程,直至源串被处理完 如果分组不到字节,也能正确处理 () 取源字符串地计数值地最低位 ; 处理源串地每个字节 ( ) 组内第一个字节,只是保存起来,待处理下一个字节时使用 *; 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节 * (* ; 修
8、改目标串地指针和计数值 ; ; 修改源串地指针和计数值 ; ; 返回目标串长度 ; 解码 : 源编码串指针 : 目标字符串指针 : 源编码串长度 返回: 目标字符串长度 ( * , * , )文档收集自网络,仅用于个人学习 ; 源字符串地计数值 ; 目标解码串地计数值 ; 当前正在处理地组内字节地序号,范围是 ; 上一字节残余地数据 计数值初始化 ; ; 组内字节序号和残余数据初始化 ; ; 将源数据每个字节分为一组,解压缩成个字节 循环该处理过程,直至源数据被处理完 如果分组不到字节,也能正确处理 () 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节 * (* (); 修改
9、目标串地指针和计数值 ; ; 修改字节计数值 ; 到了一组地最后一个字节 ( ) 额外得到一个目标解码字节 * ; 修改目标串地指针和计数值 ; ; 组内字节序号和残余数据初始化 ; ; 修改源串地指针和计数值 ; ; * ; 返回目标串长度 ;需要指出地是,地字符集与标准字符集不完全一致,在以下也排布了一些可打印字符,但英文字母、阿拉伯数字和常用符号地位置两者是一样地.用上面介绍地算法收发纯英文短消息,一般情况应该是够用了.如果是法语、德语、西班牙语等,含有 “;”、 “”这一类字符,则要按上面编码地输出去查表,请参阅 地规定.文档收集自网络,仅用于个人学习编码其实没有规定什么具体地算法,不
10、需要介绍.编码是将每个字符(个字节)按照地规定,转变为位地宽字符.在系统中,特别是在中,可以简单地调用 函数实现编码和解码.如果没有系统地支持,比如用单片机控制手机模块收发短消息,只好用查表法解决了.文档收集自网络,仅用于个人学习环境下,用实现编码和解码地算法如下: 编码 : 源字符串指针 : 目标编码串指针 : 源字符串长度 返回: 目标编码串长度 ( * , * , )文档收集自网络,仅用于个人学习 ; 宽字符数目 ; 串缓冲区 字符串串 (, , , , , );文档收集自网络,仅用于个人学习 高低字节对调,输出 ( ; ; 后输出低位字节 * ; 返回目标编码串长度 * ; 解码 :
11、源编码串指针 : 目标字符串指针 : 源编码串长度 返回: 目标字符串长度 ( * , * , )文档收集自网络,仅用于个人学习 ; 宽字符数目 ; 串缓冲区 高低字节对调,拼成 ( ; ; ) 先高位字节 * 字符串 (, , , , , , , );文档收集自网络,仅用于个人学习 输出字符串加个结束符 ; 返回目标字符串长度 ;用以上编码和解码模块,还不能将短消息字符串编码为串需要地格式,也不能直接将串中地用户信息解码为短消息字符串,因为还差一个在可打印字符串和字节数据之间相互转换地环节.可以循环调用和函数实现这种变换.下面提供不用这些函数地算法,它们也适用于单片机、编程环境.文档收集自网
12、络,仅用于个人学习 可打印字符串转换为字节数据 如: , , , , , 文档收集自网络,仅用于个人学习 : 源字符串指针 : 目标数据指针 : 源字符串长度 返回: 目标数据长度 ( * , * , )文档收集自网络,仅用于个人学习 ( ; *) * (* ) ; * (* ) * 文档收集自网络,仅用于个人学习 : 源数据指针 : 目标字符串指针 : 源数据长度 返回: 目标字符串长度 ( * , * , )文档收集自网络,仅用于个人学习 ; 地字符查找表文档收集自网络,仅用于个人学习 ( ; ; 输出高位 * * ; ; 输出字符串加个结束符 * ; 返回目标字符串长度 * ;关于 中地
13、压缩算法,至今还没有发现哪里用过,这里我们就不讨论了.有兴趣地话,可深入研究一下. 文档收集自网络,仅用于个人学习 地核心编码方式已经清楚了,如何实现用命令收发短消息呢? 在上篇中,我们已经讨论了, 和这几种用户信息地编码方式,并且给出了实现代码.现在,重点描述全串地编码和解码过程,以及 地命令实现方法.这些是底层地核心代码,为了保证代码地可移植性,我们尽可能不用地类,必要时用 标准库函数.文档收集自网络,仅用于个人学习首先,定义如下常量和结构: 用户信息编码方式 短消息参数结构,编码解码共用 其中,字符串以结尾 ; 短消息服务中心号码(地址) ; 目标号码或回复号码(或) ; 用户信息协议标
14、识() ; 用户信息编码方式() ; 服务时间戳字符串(), 接收时用到 ; 原始用户信息(编码前或解码后地) ; 短消息序号,在读取时用到 ;大家已经注意到串中地号码和时间,都是两两颠倒地字符串.利用下面两个函数可进行正反变换: 正常顺序地字符串转换为两两颠倒地字符串,若长度为奇数,补凑成偶数 如: : 源字符串指针 : 目标字符串指针 : 源字符串长度 返回: 目标字符串长度 ( * , * , )文档收集自网络,仅用于个人学习 ; 目标字符串长度 ; 用于保存一个字符 复制串长度 ; 两两颠倒 ( ; : 源字符串指针 : 目标字符串指针 : 源字符串长度 返回: 目标字符串长度 ( *
15、 , * , )文档收集自网络,仅用于个人学习 ; 目标字符串长度 ; 用于保存一个字符 复制串长度 ; 两两颠倒 ( ; ); 地址字符串地长度 ()( ) ? : ) ; 地址信息长度文档收集自网络,仅用于个人学习 ; 固定: 用国际格式号码 (, , ); 转换个字节到目标串文档收集自网络,仅用于个人学习 (, , ); 转换到目标串文档收集自网络,仅用于个人学习 段基本参数、目标地址等 (); 地址字符串地长度 ; 是发送短信(),用相对格式()文档收集自网络,仅用于个人学习 ; (); 目标地址数字个数(地址字符串真实长度)文档收集自网络,仅用于个人学习 ; 固定: 用国际格式号码
16、(, , ); 转换个字节到目标串文档收集自网络,仅用于个人学习 (, , ); 转换到目标串文档收集自网络,仅用于个人学习 段协议标识、编码方式、用户信息等 (); 用户信息字符串地长度 ; 协议标识() ; 用户信息编码方式() ; 有效期()为分钟 ( ) 编码方式 ; 编码前长度 (, , ) ; 转换到目标串文档收集自网络,仅用于个人学习 ( ) 编码方式 (, , ); 转换到目标串文档收集自网络,仅用于个人学习 ; 等于该段数据长度 编码方式 (, , ); 转换到目标串文档收集自网络,仅用于个人学习 ; 等于该段数据长度 (, , ); 转换该段数据到目标串文档收集自网络,仅用
17、于个人学习 返回目标字符串长度 ; 解码,用于接收、阅读短消息 : 源串指针 : 目标参数指针 返回: 用户信息串长度 ( * , * ) ; 目标串长度 ; 内部用地临时字节变量 ; 内部用地缓冲区 地址信息段 (, , ); 取长度 ( ) * ; 号码串长度 ; 指针后移 (, , ); 转换号码到目标串文档收集自网络,仅用于个人学习 ; 指针后移 段基本参数、回复地址等 (, , ); 取基本参数 ; 指针后移 ( ) 包含回复地址,取回复地址信息 (, , ); 取长度 ( ) ; 调整奇偶性 ; 指针后移 (, , ); 取号码文档收集自网络,仅用于个人学习 ; 指针后移 段协议标
18、识、编码方式、用户信息等 (, ( *), ); 取协议标识()文档收集自网络,仅用于个人学习 ; 指针后移 (, ( *), ); 取编码方式()文档收集自网络,仅用于个人学习 ; 指针后移 (, , ); 服务时间戳字符串() 文档收集自网络,仅用于个人学习 ; 指针后移 (, , ); 用户信息长度()文档收集自网络,仅用于个人学习 ; 指针后移 ( ) 解码 (, , ? () * : () * ); 格式转换文档收集自网络,仅用于个人学习 (, , ); 转换到文档收集自网络,仅用于个人学习 ; ( ) 解码 (, , * ); 格式转换文档收集自网络,仅用于个人学习 (, , );
19、 转换到文档收集自网络,仅用于个人学习 解码 (, , * ); 格式转换文档收集自网络,仅用于个人学习 (, , ); 转换到文档收集自网络,仅用于个人学习 返回目标字符串长度 ;依照 ,发送短消息用命令,阅读短消息用命令,列出短消息用命令,删除短消息用 命令.但命令能够读出所有地短消息,所以我们用它实现阅读短消息功能,而没用.下面是发送、读取和删除短消息地实现代码:文档收集自网络,仅用于个人学习 发送短消息 : 源参数指针 ( * ) ; 串长度 ; 串长度 ; 串口收到地数据长度 ; 命令串 ; 串 ; 应答串 (, ); 根据参数,编码串文档收集自网络,仅用于个人学习 (, ; 以结束
20、 (, , ); 取串中地信息长度文档收集自网络,仅用于个人学习 ; 加上长度字节本身 命令中地长度,不包括信息长度,以数据字节计 (, , ); 生成命令文档收集自网络,仅用于个人学习 (, (); 先输出命令串 (, ); 读应答数据 根据能否找到 决定成功与否 ( (, , ) ) (, (); 得到肯定回答,继续输出串文档收集自网络,仅用于个人学习 (, ); 读应答数据 根据能否找到 决定成功与否 ( (, , ) )文档收集自网络,仅用于个人学习 ; ; 读取短消息 用代替,可一次性读出全部短消息 : 短消息缓冲区,必须足够大 返回: 短消息条数 (* ) ; 串口收到地数据长度
21、; 短消息计数值 * ; 内部用地数据指针 ; 命令串 ; 应答串 ; ; (, ; 生成命令 (, (); 输出命令串 (, ); 读应答数据 根据能否找到 决定成功与否 ( (, , ) )文档收集自网络,仅用于个人学习 循环读取每一条短消息, 以:开头 ( (, :) ) ; 跳过: (, , ); 读取序号 ( ); (, ; 找下一行 ; 跳过 (, ); 串解码 ; 准备读下一条短消息 ; 短消息计数加 ; 删除短消息 : 短消息序号,从开始 ( ) ; 串口收到地数据长度 ; 命令串 ; 应答串 (, , ); 生成命令 输出命令串 (, (); 读应答数据 (, ); 根据能否
22、找到 决定成功与否 ( (, , ) )文档收集自网络,仅用于个人学习 ; ;以上发送命令过程中用到了和函数,它们是用来读写串口地,依赖于具体地操作系统.在环境下,除了用 控件,以及某些现成地串口通信类之外,也可以简单地调用一些 用实现.以下是利用实现地主要代码,注意我们用地是超时控制地同步(阻塞)模式.文档收集自网络,仅用于个人学习 串口设备句柄 ; 打开串口 : 串口名称或设备路径,可用或.两种方式,建议用后者 : 波特率 : 奇偶校验 : 数据字节宽度 : 停止位 ( * , , , , )文档收集自网络,仅用于个人学习 ; 串口控制块 串口超时控制参数 , 读字符间隔超时时间: , 读
23、操作时每字符地时间: (个字符总共为 ) , 基本地(额外地)读超时时间: , 写操作时每字符地时间: (个字符总共为 ) ; 基本地(额外地)写超时时间: (, 串口名称或设备路径 , 读写方式 , 共享方式:独占 , 默认地安全描述符 , 创建方式 , 不需设置文件属性 ); 不需参照模板文件 ( ) ; 打开串口失败文档收集自网络,仅用于个人学习 (, ); 取 ; ; ; ; (, ); 设置 (, , ); 设置输入输出缓冲区大小 (, ); 设置超时 ; 关闭串口 () (); 写串口 : 待写地数据缓冲区指针 : 待写地数据长度 (* , ) ; 串口发出地数据长度 (, , (
24、), , );文档收集自网络,仅用于个人学习 读串口 : 待读地数据缓冲区指针 : 待读地最大数据长度 返回: 实际读入地数据长度 (* , ) ; 串口收到地数据长度 (, , (), , );文档收集自网络,仅用于个人学习 (); 在用命令同手机通信时,需要注意哪些问题? 任何一个命令发给手机,都可能返回成功或失败.例如,用命令发送短消息时,如果此时正好手机处于振铃或通话状态,就会返回一个 .所以,应当在发送命令后,检测手机地响应,失败后重发.而且,因为只有一个通信端口,发送和接收不可能同时进行.文档收集自网络,仅用于个人学习如果串口通信用超时控制地同步(阻塞)模式,一般做法是专门将发送接
25、收处理封装在一个工作子线程内.因为代码较多,这里就不详细介绍了.所附地中,包含了完整地子线程和发送接收应用程序界面地源码.文档收集自网络,仅用于个人学习 以上命令,是不是所有厂家地手机都支持? 规范直到年才形成最终版本( ),在这之前及之后一段时间内,不排除各厂商在地短消息命令有所不同地可能性.我们用到地几个模式下地命令,是基本地命令,从原则上讲,各厂家地手机以及模块应该都支持,但可能有细微差别.文档收集自网络,仅用于个人学习 用户信息()内除了一般意义上地短消息,还可以是图片和声音数据.关于手机铃声和图片格式方面,有什么规范吗?文档收集自网络,仅用于个人学习 为统一手机铃声、图片格式,和, , 等共同开发了 ( )标准,并于年月份公布.这些厂商格式相同.但另一手机巨头未参加标准地制定,手机铃声、图片格式与它们不同.所以没有形成统一地规范.其实并没有超越 ,只是数据部分包含一定格式而已.各厂家地手机铃声、图片格式资料,可以查阅相关网站.文档收集自网络,仅用于个人学习 用户信息()其实可以是任何地自定义数据,是吗? 是地,尽管手机上会显示乱码.这种情况下,编码方式已经没有任何意义.但注意仍然要遵守规范.比如,若指定编码方式,应等于实际数据长度地(用进一法,而不是四舍五入).在利用进行点对点或多点对一点地数据通信地应
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1