关于TC35i短信发送的问题
最近忙于做自己的毕业设计,是关于单片机通过GSM收发短信的。我现在遇到了这样一个问题:就是,我基本上编程实现了短信的PDU编码发送,但是我发现有时短信成功发送后,对方手机能成功收到,有时就不能了。
程序我没做改动。
我用串口同时在电脑上看观看,单片机和GSM模块串口通信数据情况,具体如下拖:我是PDU编码发送中文“中国!”,我
发现,一个规律:就是我用CMGS命令发送出去的PDU,(1)若其只返回OK,没有返回+CMGS: <MR>消息参考值时,对方不能收到短信
(2)若其返回OK,同时有+CMGS: <MR>消息参考值时,对方能收到数据。
出现上面两种,情况是在我程序,完全没变的情况下出现的。我确定不了是哪里出现了问题。我觉得有可能是自己在发送错误信息是
改变了他的一些参数,因为我出现上面(1)。情况时,用网上找的一个手机上位机初始化下就又可以回复到(2)。但是我不知道到底
是那个参数变了。因为短信相关的参数主要好像就:CSCA,CMGF,CSMS样。但是这些好像都没变的。还请大侠们,帮忙分析下。谢了。
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_629653Q7BB5A.jpg
(1)情况没有返回消息参考值,只返回OK;(2)情况消息参考值和OK都返回了 (原文件名:1.jpg)
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_629654WKKBVO.jpg
我就用下这个软件红色圈的按键,初始化下就好了 (原文件名:2.jpg) #include "main.h"
#include "SysTick.h"
#include "Serial.h"
#include "Delay.h"
#include "Watchdog.h"
#include "eeprom.h"
#include "GSM_V1.h"
#include "Ex_Isr.h"
#include "Sms.h"
const unsigned char code *SCA_FO_MR_DA = "0011000D9168";
const unsigned char code *SMS_parameter = "0008FF";
const char code Ctrl_z[] = {0x1A, 0x00};
const unsigned char code ASIIC[]=
{
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F'
};
// 正常顺序的字符串转换为两两颠倒的字符串,若长度为奇数,补'F'凑成偶数
// 如:"8613851872468" --> "683158812764F8"
// pSrc: 待转换的源字符串指针
// pDst: 转换后的目标字符串指针
// nSrcLength: 等转换的源字符串长度
// 返回: 转换后的目标字符串长度,包含了字符串结束符'\0'的长度
unsigned char GsmInvertNumbers(unsigned char *pSrc, unsigned char *pDst, unsigned char nSrcLength)
{
unsigned char nDstLength; // 目标字符串长度
unsigned char ch; // 用于保存一个字符
unsigned char i;
nDstLength = nSrcLength; // 复制串长度
for (i=0; i<nSrcLength; i+=2) // 两两颠倒
{
ch = *pSrc++; // 保存先出现的字符
*pDst++ = *pSrc++; // 复制后出现的字符
*pDst++ = ch; // 复制先出现的字符
}
if (nSrcLength & 1) // 源串长度是奇数吗?
{
*(pDst-2) = 'F'; // 补'F'
nDstLength++; // 目标串长度加1
}
*pDst = '\0'; // 输出字符串加个结束符
return nDstLength; // 返回目标字符串长度,加上了'\0'的长度
}
/*
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 测试ok
// 字节数据转换为可打印字符串
// 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"
// pSrc: 待转换的源数据指针
// pDst: 转换后存放目标字符串指针
// nSrcLength: 待转换的源数据长度,数据长度不能大于256个字节,从1开始
// 返回: 转换后的目标字符串长度 <=0xffff,带字符串结束符'\0'。
unsigned char GsmBytes2String(const unsigned char *pSrc, unsigned char *pDst, unsigned char nSrcLength)
{
unsigned char i;
const unsigned char code tab[] = "0123456789ABCDEF"; // 0x0-0xf的字符查找表
for (i=0; i<nSrcLength; i++)
{
*pDst = tab >> 4]; // 输出高4位
pDst++;
*pDst = tab & 0x0f]; // 输出低4位
pDst++; // 转换下一个十六进制字节
}
pDst++;
*pDst = '\0'; // 输出字符串加个结束符
return (nSrcLength * 2 + 1); // 返回目标字符串长度,带字符串结束符'\0'
}
*/
请注意:
const unsigned char code *SCA_FO_MR_DA = "0011000D9168";
const unsigned char code *SMS_parameter = "0008FF";
const char code Ctrl_z[] = {0x1A, 0x00};
例子:
AT+CMGF=0
OK
AT+CSCS="UCS2"
OK
AT+CMGS=065
> 0011000D91685192659365F90008FF325C0A656C76845BA26237FF0C60A876848F668F7D65FA65FA5DF288AB89E653D1FF0C8BF75C3D5FEB524D5F8067E5770BFF01
+CMGS: 98
OK 看看是不是发送那一长串的时候多了一个换行符 楼上的,谢谢你的回复。呵呵 看你编写的大体模块好像是参照 基于GSM和单片机的远程家电控制系统(毛慧琴)论文编写的的哈 我也是参照她那个自己编写的。目前实现了发短信。
但是我出现了一个情况:就是用CMGS发送短信,TC35i的返回值:
有时只返回了OK,而没有返回+CMGS: <MR>;同样的程序:
有时又可以返回 +CMGS: <MR> 以及OK。
+CMGS: <MR> 和 OK 都返回的短信,对方能成功收到
只返回OK的短信:对方不能收到
今天上午来了,有仔细想了半天。还是没弄明白是怎么回事。还请论坛大虾指导下哈。谢谢 回复【2楼】bangbangji
-----------------------------------------------------------------------
用串口调试助手看了 两种情况发送的源PDU串是相同的。只是TC35i返回的不同:1)、OK ; 2、+CMGS: <MR> + OK 回复【4楼】jackjie
-----------------------------------------------------------------------
建议你再试试,比如你发送0011000D91685192659365F90008FF325C0A656C76845BA26237FF0C60A876848F668F7D65FA65FA5DF288AB89E653D1FF0C8BF75C3D5FEB524D5F8067E5770BFF01
最后没有换行符,有换行符是发不出去的,但也会返回OK。拷贝上去的代码在串调里发送之前也看看最后有没有换行。 判断短信发送成功请以
"+CMGS:" 字符串为准。
至于你说的那个《毛慧琴》论文,我还没有看见过。可否发上来看看。 【楼主位】 jackjie
SendString("AT+CMGS=", 0);
SendString(tmp, 0);
SendString("\r\n", 0);
GetGsmResponseValue(0, 1, "OK"); //在此处串口收到的有可能是+CMS ERROR而不是>
SendString(SMS_Buffer, 0);
GetGsmResponseValue(1, 10, "OK");
-------------------------------------------------
这里有问题,看看AT+CMGS命令解释
发送完数据长度后发送0x0d,再检测接收‘>'字符,然后再发送信息,再发送0x1A,再检测接收OK,才算完成。
两位你的模块使用流程有问题,看你的流程好像是检测到来电后才设置GSM的SMS命令,然后才发送短信,然后再挂断电话的。
这样做问题很严重。
建议你看看我的开源:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4657079&bbs_page_no=3&bbs_id=9999 回复【5楼】bangbangji
-----------------------------------------------------------------------
刚刚用串口调试助手试了:还是只返回了OK,我将你的然后试的字符串在串口你也试了
0011000D91685122381706F10008FF325C0A656C76845BA26237FF0C60A876848F668F7D65FA65FA5DF288AB89E653D1FF0C8BF75C3D5FEB524D5F8067E5770BFF01
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_629693FBRX8P.jpg
(原文件名:3.jpg) while ((!bSentSuccessfully) && (++i <= 8))
短信发送并不一定是一次就可以发送成功的,你要学会找AT命令返回值的关键字 回复【9楼】studykaka
-----------------------------------------------------------------------
谢谢你的回复,你的意思是:并不是每次短信都能成功的发送,若果遇到上面只返回OK的情况,就需要我们自己判断出来,再次重新发送,对吗? 【楼主位】 jackjie
SendString("AT+CMGS=", 0);
SendString(tmp, 0);
SendString("\r\n", 0);
GetGsmResponseValue(0, 1, "OK"); //在此处串口收到的有可能是+CMS ERROR而不是>
SendString(SMS_Buffer, 0);
GetGsmResponseValue(1, 10, "OK");
-------------------------------------------------
这里有问题,看看AT+CMGS命令解释
发送完数据长度后发送0x0d,再检测接收‘>'字符,然后再发送信息,再发送0x1A,再检测接收OK,才算完成。
两位你的模块使用流程有问题,看你的流程好像是检测到来电后才设置GSM的SMS命令,然后才发送短信,然后再挂断电话的。
这样做问题很严重。
建议你看看我的开源:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4657079&bbs_page_no=3&bbs_id=9999
/////////////////////////////////////////////////////////////////////////////////////////////////////////
呵呵,你只看到是一个表面的茫茫。
SendString("\r\n", 0);
GetGsmResponseValue(0, 1, "OK"); //在此处串口收到的有可能是+CMS ERROR而不是>
以上语句可以这样写
SendString("\r\n", 0);
GetGsmResponseValue(0, 1, ">"); //在此处串口收到的有可能是+CMS ERROR而不是>
也可以这样写:
SendString("\r\n", 0);
GetGsmResponseValue(0, 1, "我要发送短信了"); //在此处串口收到的有可能是+CMS ERROR而不是> 回复【9楼】studykaka
-----------------------------------------------------------------------
谢谢你的回复,你的意思是:并不是每次短信都能成功的发送,若果遇到上面只返回OK的情况,就需要我们自己判断出来,再次重新发送,对吗?
呵呵,你开悟了 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//针对短信息部分
smsDispatchMessage(void)
{
} 在最后发送短信的过程中,“OK”是没有意义的。
最后只有发送成功,失败,及干拢数据。
所以你要学会解述命令。
懂了这一点,GSM之类的东东可以做到通杀。 回复【14楼】studykaka
-----------------------------------------------------------------------
谢谢你的回复:你的意思我基本已经明白了,就是发送完AT+CMGS = <Len> + <回车后>;判断TC35i的返回值是不是 >,是的话:发送源PDU编码;发送完后,再次检测TC35i有没有返回:+CMGS: <MR> 和 OK (这里主要是检测返回没返回+CMGS:<MR>:若没返回,则继续回到开始从新发送,以确保发送的成功)
还有你说的要毛慧琴的论文,我是nh格式的,上传不了。你要的话留个邮箱。我给你哈 //>,提示发送SMS数据
else if (strstr((char*)GSM_V1_Receive.GSM_V1_Responses_Receive_Buffer, ">") != NULL)
{ //表示对卡操作OK
}
07GPS@163.com
页:
[1]