AT 指令发送短信详解和 C++源程序
1.
2.
AT指令发送短信详解和C++源程序...............................................................................................1
介绍...........................................................................................................................2
初始化设备...............................................................................................................2
2.1 选择串口通讯工具包.............................................................................................2
2.2 初始化.....................................................................................................................3
3. 发送短信..............................................................................................................................3
3.1 使用TEXT模式发送短信.......................................................................................3
3.2 使用PDU模式发送短信.........................................................................................4
4.接收短信.............................................................................................................................7
AT 指令发送短信说明 version:0.5
1. 介绍
IBMS
短信已经应用到我们工作生活的各个方面,但是使用手机发送短信的效率是很低的,为
了克服这个问题,我们把手机或是短信模块与 PC 相连接,发送短信,就能够能活的使用
短信服务强大方便的通讯功能。
我们公司在 TC35 模块的串口通讯基础上,通过 AT 指令开发发送接收短信的二次开发
包,满足现阶段的短信业务要求。
在开发的工作中,也遇到了很多的问题,费了不少了精力和时间,本文的目的是帮助后
继的开发人员快速的掌握 AT 指令开发短信发送程序,作为开发工程中的参考。
如果可能请先阅读以下的资料,有助于你理解 AT 指令:
1. http://www.ccw.com.cn/htm/net/seminar/02_1_22_4.asp
2. http://www.dreamfabtic.com/sms/
3. http://www.21ic.com/new_info/news/files/news/200392423133.asp
4. http://www.sendsms.cn/product/smssenddevice/pcigsmmodem2.htm
在后继的介绍中,我们重点讲解难点和我所遇到的问题,主要就是使用 PDU 格式发送
短信和怎么设置不通过 SIM 卡进行数据传输。
注:
1. 部分知识来自以上的网站,为了保护其作者的权利,特此声明。
2. 短信二次开发的软件平台为 Visual C++6.0 + Windows 2000 Pro +SP4+IE6.0,硬件
为 TC35 模块,以动态连接库的形式提供给用户使用。
3.本文将结合一个具体的类为大家讲解。
4. 还为大家介绍了 Unicode 的转换。
2. 初始化设备
2.1 选择串口通讯工具包
使用 MSComm.ocx 控件通讯,这是最简单的通讯方式,但是不能满足在这个
地方的需求,在开发项目开始的时候我也是习惯性使用的这个控件,但是在以
后的调试的过程中发现,它没有异步接收的功能,所以在同一个线程中,无法
收到发送的结果,让我郁闷了好几天。如果你不需要很复杂的控制,这个方式
也是可行的。
使用串口 API 通讯,这是很灵活的方式,网络上有很多优秀的的串口通讯封
装类。如果你要自己写,那么你一定很有时间,而且我相信你能学到比我多很
多的东西。
http://www.vckbase.com/document/viewdoc.asp?id=671
上面的网址就介绍了一个很不错的串口操作类。
深圳太极软件公司
顺德太极智能化技术开发有限公司
Page 2 of 16
作者:邓杨均
2004-1-15
AT 指令发送短信说明 version:0.5
IBMS
2.2 初始化
安装好 TC35 模块,然后选择一个通讯的串口和一定的频率,先用串口调式工具,把一
般的 AT 指令都试一遍,一般来说,这些步骤都是没有问题的。如果有问题,请马上和硬件
供应商联系。
3. 发送短信
发送短信有两种方式:TEXT 和 PDU 模式,前一种模式非常的简单,如果你只是传输数
据,而不需要使用中文,就使用 TEXT 模式就可以了。如果你需要在短信中使用中文就必须
用 PDU 模式。下面的程序为了简单使用的同步机制,如果你想要完全控制整个的过程,请
使用串口 API 异步的接收数据。
3.1 使用 TEXT 模式发送短信
1. 首先设置模式为TEXT模式:AT+CMGF=1 1,成功执行,TE2返回OK,否则返回
ERROR。
2. 然后使用:AT+CMGS=”8613802637519”,TE 返回>,就可以输入短信的内容了。
短信的内容为:data+ctrl_Z,ctrl_Z ACSⅡ中的值为 26,意思是输入结束。如果你输入
了不是 ACSⅡ字符数据,那么发送将会失败。下面是发送模块的一部分,讲述了怎么
发送 TEXT 短信.
case TEXT:
{
//ensure sending data only contains acs2
CString sCommand;
sCommand="AT+CMGF=1\r"; //TEXT mode
m_currentMode=TEXT;
ExecCmd(sCommand);
Sleep(200);
if(TEXT!=m_currentMode)
{
}
sCommand.Format("AT+CMGS=\"%s\"\r",destAddr);
ExecCmd(sCommand);
Sleep(200);
//wait TE Executed return
if(m_sComData!=">")
1 代表换行符,在C语言中为‘/r’。
2 TE:Terminal Equipment,终端设备,代表TC35 模块。
深圳太极软件公司
顺德太极智能化技术开发有限公司
Page 3 of 16
作者:邓杨均
2004-1-15
AT 指令发送短信说明 version:0.5
IBMS
}
{
}
//return FALSE;
sCommand=userData;
int length=sCommand.GetLength();
if(length>140) //the Max length of the sending data
{
}
sCommand=sCommand.Left(140);
//add end
char ctrl_z=26;
sCommand+=ctrl_z;
ExecCmd(sCommand);
Sleep(4500); //wait 4.5 seconds
break;
3.2 使用 PDU 模式发送短信
这个是本文的重点。
1. 设置输入模式为 PDU:AT+CMGF=0,成功执行,TE 返回 OK,否则返回 ERROR。
2. AT指令:AT+CMGS=,成功执行,系统返回>,然后输入PDU+ctrl_Z
问题的关键就是 PDU 编码。介绍这个方面的的资料很多,不过都是讲了我也是没有太
懂,它们也就是把 PDU 协议讲了一遍,我仍然是很迷茫,后来经过很多次痛苦的尝试,
终于成功的发送了一条中文的短信。
3. 先给出生成 PDU 数据这部分的源程序。
/*****************************************************************************
* Class : CGModem
* Function : HandleResponse
* Description: Handle the answer string
* Parameters : sDestAddr: the phone number who receive the SM
*
*
* Return :
******************************************************************************/
CString CGModem::CreatePduSms(CString sDestAddr,CString userData, UINT *nDataLength)
userData: the content of the sm
nDataLength: the length of the PDU exclude the CSCA
3 这个参数和函数CreatePduSms的nDataLength是一致的。
深圳太极软件公司
顺德太极智能化技术开发有限公司
Page 4 of 16
作者:邓杨均
2004-1-15
AT 指令发送短信说明 version:0.5
IBMS
CString sResult;
sResult="00";
sResult+="1100";
//固定格式
//固定格式
//address style
sResult+="0D91";
char sNO[20];
memset(sNO,0,sizeof(sNO));
strcpy(sNO,sDestAddr);
char sMS[160];
strcpy(sMS,userData);
int length=userData.GetLength();
//normal address format to BCD format
sResult+=to_BCD(sNO,sDestAddr.GetLength());
sResult+="00"; //TP-PID
sResult+="08"; //TP-DCS,UCS2
sResult+="A7"; //TP-Validity-Period
{
}
这个函数使用了几个公共的函数,为了不干扰主题,在文章的最后,我们会给出这些函
数。然后在发送模块中调用这个函数。
深圳太极软件公司
顺德太极智能化技术开发有限公司
sResult+=Int2HexString(sLetter.GetLength()/2);
sResult+=sLetter;
sResult.MakeUpper();
sResult.TrimLeft();
*nDataLength=sResult.GetLength()/2-1;
return sResult;
//UCS2 to int string
for(int i=0; i
AT 指令发送短信说明 version:0.5
IBMS
Sleep(200);//wait execute return
if(m_sComData.Find(">"))
{
//
}
return FALSE;
sCommand="AT+CMGF=0\r"; //UDP Mode
m_currentMode=UDP;
ExecCmd(sCommand);
Sleep(100);
case UDP ://default
{
UINT nDataLength=0;
CString sData=CreatePduSms(destAddr,userData,&nDataLength);
CString sCommand;
if(UDP!=m_currentMode)
{
}
sCommand.Format("AT+CMGS=%d\r",nDataLength);
ExecCmd(sCommand);
/*****************************************************************************
* Class : CGModem
* Function : SendSms
* Description: Send a Short message by AT command
* Parameters : destAddr: the mobile number who recive the SM
深圳太极软件公司
顺德太极智能化技术开发有限公司
4.发送短信函数的原型为:
//the end character
char ctrl_z=26;
sCommand+=ctrl_z;
int iSize=m_commandSet.GetSize();
Sleep(4500); //wait 4.5 seconds
break;
ExecCmd(sCommand);
}
sCommand=sData;
Page 6 of 16
作者:邓杨均
2004-1-15
AT 指令发送短信说明 version:0.5
IBMS
TEXT in TEXT Mode
userData: the content of SM
nSmsFormat: UDP in UDP Mode (default)
*
*
*
* Return :
******************************************************************************/
BOOL CGModem::SendSms(LPCTSTR destAddr, LPCTSTR userData, UINT nSmsFormat/*=UDP*/)
调用这个函数,就可以发送短信了。
比如:SendSms("8613802637519","你好,世界"),就会往串口传输如下的数据:
AT+CMGS=25
0011000D91683108627315F90008A70A4F60597DFF0C4E16754C
4.接收短信
iProperty;
iMemClass;
iIndex;
cSender[20];
cTimeStamp[24];
// (REC UNREAD 1:REC READ 2:STO UNSENT 3:STO SENT)
int
char
char
char cMessage[160];
int
int
如果你需要 TE 有新的短信的时候提醒你,可以在初始化设备的时候,写入命令:
AT+CNMI=1,1,0,0,1 就 可 以 在 新 的 信 息 到 来 的 时 候 , 提 醒 你 。 然 后 使 用
AT+CMGR=读取短信。Index 是短信在 TE 中存储的位置索引。可以从新短信
的到达的提示中获得这个索引,也可以使用 CMGL 列出各种类型的短信,详细的使用方法
你可以参看 AT 指令集。
接收的关键是在于解析 UDP 数据。我们下面给出这个函数:
函数返回结构体:
struct STRU_SMS
{
};
/*****************************************************************************
* Class : CGModem
* Function : ResolvePduSm
* Description: Resolve UDP format data
* Parameters : sReceiveData: the UDP data
*
*
*
* Return : sm struct contained the all information
******************************************************************************/
STRU_SMS CGModem::ResolvePduSm(CString sReceiveData, int iLength, int iProperty, int
iCurrentIndex)
{
深圳太极软件公司
顺德太极智能化技术开发有限公司
iLength: the length of valid UDP data exclude the CSCA address
iProperty: indicate the states of message in memory
iCurrentIndex: the index of sm to resovle
作者:邓杨均
2004-1-15
Page 7 of 16
AT 指令发送短信说明 version:0.5
IBMS
//the data is can't empty.
ASSERT(0!=sReceiveData.GetLength());
STRU_SMS newSm;
memset(&newSm,0,sizeof(STRU_SMS)); //initialize
newSm.iIndex=iCurrentIndex;
newSm.iProperty=iProperty;
//Get Valid data
CString sData=sReceiveData.Right(iLength*2);
//Get Sender number----------------------------------------
iLengthAddr=13;
//Get Address length
int iLengthAddr;
if("0D"==sData.Mid(2,2))
{
}
else
{
}
深圳太极软件公司
顺德太极智能化技术开发有限公司
//BCD Transilation
char cSender[20];
ASSERT(FALSE);
CString sSender=sData.Mid(6,iLengthAddr+1); //extra 'F'
memset(cSender,0,sizeof(cSender));
strcpy(cSender,sSender);
sSender=from_BCD(cSender,sSender.GetLength());
//trim 'F'
sSender.TrimRight("F");
strcpy(newSm.cSender,sSender);
//Get TimeStamp--------------------------------------------
Page 8 of 16
作者:邓杨均
2004-1-15