http://blog.csdn.net/dlutxie/article/details/7848623

GSM PDU模式发中文短信 网上的资料也有很多,但参考了这么多天才最终搞定,所以还是把自己的一点点体会写出来,做为记录,也方便其它后来者参考。

网上的资料很多都没有讲开发的环境,所以有些地方我还是感到很疑惑。

本人的开发环境:

硬件:GSM模块用的是西门子公司的MC52i, 控制心片为STM32, STM32与MC52i通过串口直接通信

开发环境:IAR ARM版,版本号忘了。

开发语言:C语言,没有用操作系统啥的。

手机卡:手机卡即为我自己手机使用的卡,中国移动动感地带。

一些参考资料:

AT发中文短信:http://bbs.chinaunix.net/thread-1945962-1-1.html

SMS中用Unicode编码发送中文:http://www.pc6.com/infoview/Article_405.html

UTF-8, Unicode, GB2312格式串转换之C语言版:http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html

Unicode 编码介绍:http://www.willar.com/article/article_view.asp?id=474

GSM无线模块短消息PDU 格式说明:
http://www.cnblogs.com/AlphaDu/articles/1233121.html
http://www.dreamfabric.com/sms/
http://read.pudn.com/downloads30/doc/comm/94938/mc35i%E5%8F%8Atc35i%E6%8C%87%E4%BB%A4/qunfa2.pdf

相关参考文档(有官方技术手册):http://download.csdn.net/detail/dlutxie/4488089

由于MC55i与MC52i的命令基本一样,所以我参考的是MC55i的用户手册,在该手册中有详细的设置流程图,里面会讲哪些命令是必须执行,哪些是可选。

先按该手册中的介绍,发送短信模块的初始化如下:

AT+CSCS = “GSM”; //设置终端设备字符集,应该就是设置该GSM模块的字符集吧,默认情况即为GSM字符集。发送的时候:sentCom("AT+CSCS =\ “GSM\”");注意这里用了解引用。

AT + CSCA = +8613800411500//设置信息中心的号码,该号码对于一个手机卡来说是确定的,可以在手机的短信设置里面看到。该命令的设置还可能为AT+CSCA=“+13800411500”,多了个引号,后面还可以带一个参数的,AT+CSCA=+8613800411500,145; 145表示前面给的号码是国际号码,以+号开头,并带有国家标号;或者AT+CSCA=13800411500,129; 129表示不确定前面的号码是否是国家还是国际号码可带可不带国家标号,不要以+号开头。具体的我没有测试,查看的了不是官方文档。如果是要通过串口发送该命令可以写为:sentCom("AT+CSCA=\“+13800411500\”");注意这块有个对引号进行解引用。

AT+CSMS=1; //设置消息服务:GSM 07.05 Phase2+

AT+CNMI=2,1,0,1;//设置收到信息时的提示模式

AT^SMGO=1;//用URC形式提示SMS存储空间是否满,0不提示,1表示提示。

AT+CMGF=0;//设置发送信息的模式,0表示PDU模式,1表示文本模式,默认情况一般是0,但我的手机卡默认似乎是1

AT+SCMP=17, 167,0,0;//如果是文本形式发送,则需设置该参命令

AT&W;//将上面的设置存入用户配置文件中,这样下次上电加载时就可以不用再做这些设置了。这里的用户配置文件指的是在MC52i中还是SIM卡中呢?

好了,上面所说的是官方文档要求的流程,现在来看看我的实际情况吧:

AT+CSCS = “GSM”; 对于该条命令,我将字符集设为UCS2,即AT+CSCS = “USC2”; 不管是文本模式还是PDU模式发送中文还是英文短信,信息都是发送失败,所以最后选择的是默认的GSM字符集就正常了。

AT + CSCA = +13800411500;在用文本模式发送短信时,设置了该信息中心号码,发送短信还出错了,发不出去,忘了是不是和前面的选择字符集有关。我用AT+CSCA=?进行测试,该命令能返回OK,但进行执行读命令:AT+CSCA?却总是出错,有两次返回的却是很长的一串看不懂的数字串:+CSCA:"002B0038003600310033003800300030003400310031003500300030,145",后面的145应该就是表示前面的号码是国际号,也许该信息中心号码是进行了加密?有看到文档说该信息中心号码是存在SIM卡里的,而不是GSM模块里的,发送短信时,GSM模块该会去SIM卡中读取该号码(PS,我没在官文档中明确的看到,当然我看的资料肯定也不全)。所以在用文本模式发送短信时,我没有设置该信息中心号码,短信反而还发送出去了!!!

上面接下来的六条命令除了AT+CMGF=0;外,其它五条命令都可以选用默认值!当然该条命令也可以选用默认值的,就是要看你以何种形式发送短信了。

所以总结来说,如果以文本模式发送短信只需执行如下命令:

sentCom("AT+CMGF=1");//选用文本模式

delay(100);//延时100ms,在MC52i的官方文档中有指出,每条命令执行后一般需要100ms左右才能执行下一条命令,有些命令需要的延时会更长,比如打开网络连接命令。

sentCom("AT+CMGS=18608683863");//设置目的手机号

delay(100);//延时100ms,如果能发送短信,则会反回一个“>”提示符,等待输入短信文本。

print("Please sent me a message back by qq, thx");//发送短信文本,注意以文本形式发送短信是不支持中文的,如果这里输入了中文或中文符号则会出错

print("\x1a");//以十六进制的形式输入Ctrl+Z, 结束短信

delay(5000);//延时5s,注意,这里的延时很重要,当时我延的是2s都没有收到MC52i模块的回复,所以都不知道该命令是否执行成功,最后才发现是延时不够,这块的延时可让我花了些时间,搞不懂问题出中哪了!!MC52i中的命令延时是很重要的,但在网上的一些资料里很少有见到强调这一点的。

如果以PDU的模式发送短信,需要执行的命令如下:

sentCom("AT+CMGF=0");//选用PDU模式

delay(100);//延时100ms

sentCom("AT+CMGS=25");//如果能发送短信,即该命令执行成功则会返回一个">"提示符,等待输入短信文本,写程序的时候可以用一个if判断下。

print("0011000D91685178722902F00008000A5DE54F5C61095FEBFF01");//短信内容为“工作愉快!”四个字加个叹号,

print("\x1a");//以十六进制的形式输入Ctrl+Z, 结束短信

delay(5000);//延时5s,注意,这里的延时很重要,当时我延的是2s都没有收到MC52i模块的回复,所以都不知道该命令是否执行成功,最后才发现是延时不够,这块的延时可让我花了些时间,搞不懂问题出中哪了!!MC52i中的命令延时是很重要的,但在网上的一些资料里很少有见到强调这一点的。

PS:sentCom("AT+CMGS=25");该条命令中的25是从PDUtype开始(即从CSCA后一个字节开始)算起直到最符所有字符的字节数,即字符数/2。对于上面的那条信息,即指:11000D91685178722902F00008000A5DE54F5C61095FEBFF01所占用的字节数,注意是字节数而不是字符数!!如果想偷懒,可以把该字符串复到word07或10中,然后选中,点击状态栏中的字符数即可查看到有多少字符,然后除以2即是字节数。有的文档说这里的长度指的是要发送数据的最大字节数,比如这里的25指最大发送25字节(不包括CSCA),实际发送的字节数可以少于该数,但在我的测试中,该值只能是实际发送数据的字节数,否则就会出错!

0011000D91685178722902F00008000A5DE54F5C61095FEBFF01该条信息的第一个字节00表示选择 AT + CSCA = +8613800411500命令中设置的信息中心号码,故该PDU中就省去了该信息中心号码,但在我的程序中也并没有执行 AT + CSCA = +8613800411500命令,信息还是发送出去了,应该是SIM卡中就有该信息中心号码的信息。

该PDU还可以换成:0891683108401105F011000D91685178722902F00008000A5DE54F5C61095FEBFF01,短信内容为“工作愉快!”四个字再加个叹号, 发送的字节数仍然还是25和上一条PDU是一样的,只是加上了信息中心的号码而已!

在这里对:0891683108401105F011000D91685178722902F00008000A5DE54F5C61095FEBFF01该PDU进行简单的解释下:

首先对该PDU进行分段:0891683108401105F0  1100  0D91685178722902F0  000800  0A5DE54F5C61095FEBFF01

第一段为CSCA,即信息中心号码:08 91 683108401105F0 :08为“91683108401105F0”的字节长度(字符数/2) 91表示国际号码,所以在号码中加有国家标志,86代表中国,该信息中心的实际号码为:8613800411500,将每两位数字为一组,然后前后交换即得到前面的表示形式。更详细的请参考我所提供的资料中有详细介绍。

第二段:1100, 11:该字节即为PDUtype, 表示为发送短信,而不是接收短信,当然该字节中还包含有其它意思,具体的请参考相关文档。00:为TP-MR,信息参考,每发送一条短信,信息中心将对该值自动加1,一般都设为00。

第三段为目的手机号码:0D 91 685178722902F0 ,OD为目的手机号(8615872792200)的字符长度的十六进制表示,十进制为13,注意这里指的是字符长度,而不是字节数,这个计算与信息中心号码的长度计算有区别!!所以该长度不包括91,也不包括补充上来的那个F。91表示国际号码。这里的实际号码为:8615872792200。

第四段为数据编码:000800  这里的08表示采用UCS2编码而并不是网上一些资料说的8位编码,8位编码该位可以用04或者F6等,具体的可以参考相关资料。如果这里改为04,即采用8编码,而我这个PDU的短信内容仍然用Unicode编码,即0A5DE54F5C61095FEBFF01这样,短信发送执行命令返回的是OK,但对方却没有收到短信!!!其它两字节这里不作详细介绍(前面的00为PID,后面的00为信息中心保留信息的时间)。

第五段为信息内容:0A 5DE54F5C61095FEBFF01,0A表示信息的长度,即指这里的“5DE54F5C61095FEBFF01”的字节长度,该中文采用的是Unicode,然后经过转换为UCS2编码。

所以最后该PDU表示的信息为:

信息中心号码为:+8613800411500

目的手机号码为:+8615872792200

短信内容为:工作愉快!

最后附上sentCom()和print函数:

void sentCom(unsigned char *pd) 
{
    RxCounter = 0; //重置接收缓冲区计数器
    print( pd );
    print("\r\n"); //发送完命令的标志,也可以只输入:\r

}

void print(unsigned char *pd) 
{
    while(( * pd )!='\0')
    {
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); //STM32串口1
        USART_SendData(USART1, *pd);
pd++;
    }
PS: AT+CPIN?  //检查SIM卡工作是否正常,返回READY表明正常
AT+CSQ 检测信号质量, +CSQ:99,0  表示:not known or not detectable

GSM PDU模式发中文短信相关推荐

  1. gsm模块发中文短信

    用两条AT指令发中文短信 设置为PDU模式 AT+CMGF=0或1回车 //设置短信编码方式  0为PDU模式 1为TEXT模式 TEXT模式只支持字母或数字,要发中文短信,只能用PDU模式 C表达如 ...

  2. Iphone5 语言设置成英文后如何发中文短信

    老革命遇到新问题: 由于工作环境关系, 我的手机语言一直设置成英文. 之前用过的iphone和其他手机,在需要发送短信时可以直接选择所要输入的语言. 看似很平常的要求,在Iphone5上却遇到了新情况 ...

  3. sms+cmgs+pdu+java_实现sms短信发送+pdu模式(支持中英文发送)

    以下部分资料是从网上各个博客收集到的: 1.目前,发送短消息常用Text和PDU(Protocol Data Unit,协议数据单元)模式. 1>使用Text模式收发短信代码简单,实现起来十分容 ...

  4. Wavecom gsm 模块发送中文短信

    Wavecom gsm 模块发送中文短信 这今天被wavecom 模块发送中文短信的事搞的头大,不过最后还是成功了. 说一说整个事的过程吧! 首先说一下这个事情的背景: 我们公司有条产品线是嵌入式计算 ...

  5. 通过STC15F2K60S2控制SIM900A发中英文短信,打电话

    本文通过串口通信,使用STC15系列单片机实现发短信打电话功能. 一. 注意事项 1. 首先要确定手机卡已经注册到网络,具备打电话发短信功能 2. 正确的硬件连接: P3.0-----STXD或者5V ...

  6. 51单片机控制SMI800Cgsm模块发送中文短信

    使用AT89C51单片机控制SMI800Cgsm模块发送中文短信.使用STM32发送短信敬请等待... #include "config.h" #include "str ...

  7. 使用MircoPython转换PUD编码发送中文短信

    利用MircoPython的ESP32驱动安信可的A9发短信时,发现其发送中文短信的PUD编码资料有点少.经测试后总结如下: 文章目录 一.PUD编码结构 简单应用版: 具体结构: PUD编码测试网站 ...

  8. 如何利用 LTE/4G 伪基站+GSM 中间人攻击攻破所有短信验证

    这次公开课请来的嘉宾对自己的简介是: 连续创业失败的创业导师: 伪天使投资人: 某非知名私立大学创办人兼校长: 业余时间在本校通信安全实验室打杂. 自从他在黑客大会上演讲<伪基站高级利用技术-- ...

  9. Python操作SIM800C发送中文短信

    前言 项目上需要实现一个自动发送短信的功能, 由于是内网环境, 所以不能调用阿里之类的短信业务, 于是想着着手从传统的短信猫方式进行实现, 不过某宝上现在已经屏蔽了短信猫相关的关键词, 不过可以搜US ...

最新文章

  1. 5月26 留言板练习题
  2. Python单元测试之pytest
  3. Android开发之Android5.1.1(CM12.1)源码中短信发送流程解析
  4. Verilog | HDL 音乐盒设计(代码类)
  5. java 圆桌_约瑟夫问题求解释(圆桌问题)Java
  6. 简单思维dp-- Gym - 102392B
  7. 如何高效学习java呢?
  8. document.body.scrollTop用法
  9. arcgis server 9.3 查看地图服务时出现No Content错误
  10. 操作系统 第五章 IO管理
  11. 很多中小企业都在用的3款开源软件被曝多个漏洞
  12. Android基于mAppWidget实现手绘地图(一)--简介
  13. 工具篇1-CMDER--windows下工具,模拟linux好用的工具
  14. java基本操作-2
  15. pip下载太慢?聪明人都这样
  16. 电脑查找电子书资源,speedceo浏览器下载PDF文件阅读分享
  17. 怎么通过抖音带货赚钱?史上最全面抖音带货攻略
  18. db4o_8.0对象数据库官方文档翻译_学习笔记三
  19. java7大设计原则
  20. 电工结业试卷_电工学试卷A答案.docx

热门文章

  1. 网狐大联盟机器管理工具编译与使用
  2. IntelliJ Idea 常用快捷键列表
  3. java计算机毕业设计ssm学生宿舍管理系统15pjb(附源码、数据库)
  4. Accumulation Degree题解
  5. java求美国数学家的年龄_陶哲轩8岁在美国高考得760分,智商超爱因斯坦30%,现状如何了?...
  6. 金山云发布感知评价指标KPA 拨开遮挡高清视频技术的迷雾
  7. NAO机器人高尔夫中的视觉系统设计
  8. 前端学习笔记一:HTML(1)预备知识及一个简单的网页
  9. Unity3D-打飞碟小游戏
  10. docker 安装kafka