AT命令遇到问题,我用AT+CMGR=1 读到某种短信就变数字

scum2006 2010-12-01 07:55:41
我先设置了文本模式,发了一条内容为“I want order sth.”的短信到modem,再读取短信,一切正常。

AT+CMGF=1

OK

AT+CMGR=1

+CMGR: "REC READ","+6596520861",,"10/11/30,13:28:53+32"
I want order sth.

OK

=========================================

我用AT+CMGD删除了所有短信,又发了一条“U:080034E;L:18;T:1420;”的短信到猫里面,再读取,可是读到的全是数字

+CMGR: "REC UNREAD","+6596520861",,"10/11/30,16:09:08+32"
0055003A0030003800300030003200330051003B0054 003A0031003400320030003B0044003A00310038003B


这是什么回事呢?我的程序启动初始化时第一件事就是设置了文本模式,AT+CMGR=1
有劳高手帮忙分析一下,谢谢


...全文
1499 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangl3215 2011-10-14
  • 打赏
  • 举报
回复
学习 了
现在还是人类 2010-12-03
  • 打赏
  • 举报
回复
VB本身没有PDU编码解码的东西,编码解码需要自己写过程.
以下是我在VC里写的一个PDU解码过程,你可以参考一下。
虽然里面有些是非标的类(自己的类),但大致过程应该还是很清楚的。

//**************************************************************************
//** 函 数 名:PDUDecode
//** 功能描述:对读取到的 SMS 短信进行 PDU 解码。
//** 参数输入:strPDUString - 必要参数。要解码的 PDU 字符串。
//** :retPhone - 必要参数。解码后返回来电号码的字符串缓冲区。
//** :retDateTime - 必要参数;解码后返回短信时间的字符串缓冲区。
//** 返 回:成功返回短信正文信息,失败返回空字符串
//** 创建日期:2010-09-10
//** 修改日期:
//** 版 本 号:(VC版本) Version 1.0.0
//**************************************************************************
char * PDUDecode(char * strPDUString, char ** retPhone, char ** retDateTime)
{
//收到短信的基本段落模式
//SCA + PDU Type + OA + PID + DCS + SCTS + UDL + UD
VBString PDUString;
VBString tmpString;
VBString tmpStr1;
VBString SCAText;
VBString OAText;
VBString SCTSTime;
VBString UDText;
VBString UDASCII;
WORD UDUnicode = 0;
WORD UDGB2312 = 0;
//BSTR retBSTR;
BYTE MoveBitCount = 0;
BYTE YSBYTE = 0;
BYTE BJBYTE = 0;
BYTE TMPBYTE = 0;


DWORD ExecByteCount = 0;
DWORD SCACount = 0;
DWORD OACount = 0;
DWORD SCAMode = 0;
DWORD OAMode = 0;
DWORD tmpLong1 = 0;
DWORD DCSZip = 0;
DWORD DCSCode = 0;
DWORD UDCount = 0;
DWORD Y = 0;
PDUString = strPDUString;

//====== 分析 SCA 段信息 ======
ExecByteCount = 2;
tmpString = PDUString.get_Mid(0,2);
//=== 分析 SCA 的 Len 段 ===
SCAText = "";
if(tmpString!="00"){
//如果不是 00 表示存在短信中心号码信息
sscanf(*tmpString,"%x",&SCACount);
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&SCAMode);
//=== 分析 SCA 的 Type 段 ===
//分析 Type 段的 数据类型段 Bit 6-4
tmpLong1 = SCAMode << 1;
tmpLong1 = tmpLong1 & 0xFF;
tmpLong1 = tmpLong1 >> 5;
switch(tmpLong1){
case 0: //未知的类型,这里不做处理
break;
case 1: //国际类型,表示 + 开头
SCAText = "+";
break;
case 2: //国内号码类型
break;
case 7: //留作扩展
break;
}
//分析 Type 段的 号码鉴别段 Bit 3-0
tmpLong1 = SCAMode & 15;
switch(tmpLong1){
case 0: //未知
break;
case 1: //ISDN/电话号码(E.164/E.163)
break;
case 15://留作扩展
break;
}
//=== 分析 SCA 的 Add 段 ===
for(Y = ExecByteCount;Y<=(ExecByteCount+((SCACount - 2) * 2));Y=Y+2){
tmpString = PDUString.get_Mid(Y, 2);
SCAText &= tmpString.get_Right(1);
SCAText &= tmpString.get_Left(1);
}
tmpString = SCAText.get_Right(1);
if(tmpString=="F"){
SCAText.set_Left(SCAText.lengthB-1);
}
ExecByteCount = ExecByteCount + ((SCACount - 1) * 2);
}
//====== 分析 PDU Type 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
//====== 分析 OA 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
OAText = "";
if(tmpString!="00"){
// 如果不是 00 表示存在发送用户的号码信息
sscanf(*tmpString,"%x",&OACount);
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&OAMode);
//=== 分析 OA 的 Type 段 ===
//分析 Type 段的 数据类型段 Bit 6-4
tmpLong1 = OAMode << 1;
tmpLong1 = tmpLong1 & 0xFF;
tmpLong1 = tmpLong1 >> 5;
switch(tmpLong1){
case 0: //未知的类型,这里不做处理
break;
case 1: //国际类型,表示 + 开头
OAText = "+";
break;
case 2: //国内号码类型
break;
case 7: //留作扩展
break;
}
//分析 Type 段的 号码鉴别段 Bit 3-0
tmpLong1 = OAMode & 15;
switch(tmpLong1){
case 0: //未知
break;
case 1: //ISDN/电话号码(E.164/E.163)
break;
case 15://留作扩展
break;
}
//=== 分析 OA 的 Add 段 ===
if(OACount%2==1){
tmpLong1 = OACount + 1;
}else{
tmpLong1 = OACount;
}
tmpString = PDUString.get_Mid(ExecByteCount,tmpLong1);

for(Y = 0;Y<tmpLong1;Y=Y+2){
tmpStr1 = tmpString.get_Mid(Y, 2);
OAText &= tmpStr1.get_Right(1);
OAText &= tmpStr1.get_Left(1);
}
if(OACount%2==1){
OAText.set_Left(OAText.lengthB-1);
}
ExecByteCount = ExecByteCount + tmpLong1;
}
//====== 分析 PID 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
//====== 分析 DCS 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&tmpLong1);
// 分析 DCS 的是否压缩标志 Bit 5
tmpLong1 = tmpLong1 >> 4;
DCSZip = tmpLong1 & 1; // 0 - 表示未压缩 1 - 表示用 GSM 标准压缩算法压缩
// 分析 DCS 的编码防止标志 Bit 3-2
sscanf(*tmpString,"%x",&tmpLong1);
tmpLong1 = tmpLong1 >> 2;
DCSCode = tmpLong1 & 3; // 0 - 表示用 7 Bit 位编码(英文) 1 - 表示用 8 Bit 位编码(数据) 2 - 表示用 16 Bit 位的 UCS2 编码(中文) 3 - 预留
//====== 分析 SCTS 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,12);
ExecByteCount = ExecByteCount + 14;
SCTSTime = "";
for(Y=0;Y<12;Y=Y+2){
tmpStr1 = tmpString.get_Mid(Y,2);
SCTSTime &= tmpStr1.get_Right(1);
SCTSTime &= tmpStr1.get_Left(1);
}
tmpString = *SCTSTime;
SCTSTime = tmpString.get_Mid(0,2);
SCTSTime &= "-";
SCTSTime &= tmpString.get_Mid(2,2);
SCTSTime &= "-";
SCTSTime &= tmpString.get_Mid(4,2);
SCTSTime &= " ";
SCTSTime &= tmpString.get_Mid(6,2);
SCTSTime &= ":";
SCTSTime &= tmpString.get_Mid(8,2);
SCTSTime &= ":";
SCTSTime &= tmpString.get_Right(2);
//====== 分析 UDL 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&UDCount);
//====== 分析 UD 段信息 ======
UDASCII = "";
switch(DCSCode){
case 0: //表示用 7 Bit 位编码(英文)
UDCount = UDCount - (UDCount / 8);
UDCount = UDCount * 2;
UDText = PDUString.get_Mid(ExecByteCount,UDCount);
tmpStr1 = "A";
for(Y=0;Y<UDCount;Y=Y+2){
tmpString = UDText.get_Mid(Y,2);
sscanf(*tmpString,"%x",&tmpLong1);
MoveBitCount++;
if(MoveBitCount==1){
YSBYTE = (BYTE)(tmpLong1 & 255);
BJBYTE = YSBYTE;
YSBYTE = YSBYTE << MoveBitCount;
YSBYTE = YSBYTE >> MoveBitCount;
BJBYTE = BJBYTE >> (8-MoveBitCount);
}else if(MoveBitCount>=7){
YSBYTE = (BYTE)(tmpLong1 & 255);
TMPBYTE = YSBYTE;
YSBYTE = YSBYTE << MoveBitCount;
YSBYTE = YSBYTE >> 1;
YSBYTE = YSBYTE | BJBYTE;
BJBYTE = TMPBYTE >> (8 - MoveBitCount);
tmpStr1.value[0] = (char)YSBYTE;
UDASCII &= *tmpStr1;
YSBYTE = BJBYTE;
MoveBitCount = 0;
}else{
YSBYTE = (BYTE)(tmpLong1 & 255);
TMPBYTE = YSBYTE;
YSBYTE = YSBYTE << MoveBitCount;
YSBYTE = YSBYTE >> 1;
YSBYTE = YSBYTE | BJBYTE;
BJBYTE = TMPBYTE >> (8 - MoveBitCount);
}
tmpStr1.value[0] = (char)YSBYTE;
UDASCII &= *tmpStr1;
}
break;
case 1: //表示用 8 Bit 位编码(数据)
UDText = PDUString.get_Mid(ExecByteCount,UDCount*2);
for(Y=0;Y<UDCount;Y++){
tmpString = UDText.get_Mid(Y*2,2);
sscanf(*tmpString,"%x",&tmpLong1);
UDASCII &= (char *)(BYTE)tmpLong1;
}
break;
case 2: //表示用 16 Bit 位的 UCS2 编码(中文)
UDCount = UDCount / 2;
UDText = PDUString.get_Mid(ExecByteCount,(UDCount * 4));
tmpStr1 = "AA";
UDCount = UDCount * 4;
for(Y=0;Y<UDCount;Y=Y+4){
tmpString = UDText.get_Mid(Y,4);
sscanf(*tmpString,"%x",&UDUnicode);
UDGB2312 = GB2312[UDUnicode];
if(HIBYTE(UDGB2312)==0){
tmpStr1.value[0]=LOBYTE(UDGB2312);
tmpStr1.value[1]=HIBYTE(UDGB2312);
}else{
tmpStr1.value[0]=HIBYTE(UDGB2312);
tmpStr1.value[1]=LOBYTE(UDGB2312);
}
UDASCII &= *tmpStr1;

}
break;
}
*retPhone = *OAText;
*retDateTime = *SCTSTime;
return *UDASCII;
}
现在还是人类 2010-12-02
  • 打赏
  • 举报
回复
最好不要用文本模式,因为现在的短信基本都是用PDU编码发的,
在解码的时候,无论发送的时候是什么模式,都可以用PDU方式
解释出来,而文本模式就没有那么通用。他只能处理英文的内容。
建议你还是从PDU码入手好一点。
scum2006 2010-12-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 supermanking 的回复:]

最好不要用文本模式,因为现在的短信基本都是用PDU编码发的,
在解码的时候,无论发送的时候是什么模式,都可以用PDU方式
解释出来,而文本模式就没有那么通用。他只能处理英文的内容。
建议你还是从PDU码入手好一点。
[/Quote]

那我用PDU模式读取的内容用什么方法转换成文本?
vb本身是不是有相对的接口可以处理?
scum2006 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 dbcontrols 的回复:]

VB code
MSComm1.Output = "AT+CMGF=0" & vbCr '使用PDU模式
[/Quote]

PDU 模式出来的应该就不是文本了,可是我要的是文本啊。。。。
等实验室开门了,我再去试试,谢谢
dbcontrols 2010-12-01
  • 打赏
  • 举报
回复
MSComm1.Output = "AT+CMGF=0" & vbCr '使用PDU模式
scum2006 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 veron_04 的回复:]

仔细研究通信协议。。。
[/Quote]

兄台,能不能详细一点啊?
我是com端口连接modem,用vb编写控制modem,

发了好些短信到modem上,读取都没有问题,
可是发那个内容为“U:080034E;L:18;T:1420;”的短信, 读出来就全是数字,
感觉不是文本模式设置不好
贝隆 2010-12-01
  • 打赏
  • 举报
回复
仔细研究通信协议。。。

863

社区成员

发帖
与我相关
我的任务
社区描述
VB COM/DCOM/COM+
c++ 技术论坛(原bbs)
社区管理员
  • COM/DCOM/COM+社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧