搜索
bottom↓
回复: 16

关于TC35i短信发送的问题

[复制链接]

出0入0汤圆

发表于 2011-4-9 22:10:51 | 显示全部楼层 |阅读模式
最近忙于做自己的毕业设计,是关于单片机通过GSM收发短信的。我现在遇到了这样一个问题:
      就是,我基本上编程实现了短信的PDU编码发送,但是我发现有时短信成功发送后,对方手机能成功收到,有时就不能了。
程序我没做改动。
      我用串口同时在电脑上看观看,单片机和GSM模块串口通信数据情况,具体如下拖:我是PDU编码发送中文“中国!”,我
发现,一个规律:就是我用CMGS命令发送出去的PDU,(1)若其只返回OK,没有返回+CMGS: <MR>消息参考值时,对方不能收到短信
                                               (2)若其返回OK,同时有+CMGS: <MR>消息参考值时,对方能收到数据。                                 
出现上面两种,情况是在我程序,完全没变的情况下出现的。我确定不了是哪里出现了问题。我觉得有可能是自己在发送错误信息是
改变了他的一些参数,因为我出现上面(1)。情况时,用网上找的一个手机上位机初始化下就又可以回复到(2)。但是我不知道到底
是那个参数变了。因为短信相关的参数主要好像就:CSCA,CMGF,CSMS样。但是这些好像都没变的。还请大侠们,帮忙分析下。谢了。

(1)情况没有返回消息参考值,只返回OK;(2)情况消息参考值和OK都返回了 (原文件名:1.jpg)


我就用下这个软件红色圈的按键,初始化下就好了 (原文件名:2.jpg)

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2011-4-10 09:35:00 | 显示全部楼层
#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[pSrc >> 4];                                        // 输出高4位
                pDst++;
                *pDst = tab[pSrc & 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

出0入0汤圆

发表于 2011-4-10 10:23:16 | 显示全部楼层
看看是不是发送那一长串的时候多了一个换行符

出0入0汤圆

 楼主| 发表于 2011-4-10 10:29:30 | 显示全部楼层
楼上的,谢谢你的回复。呵呵 看你编写的大体模块好像是参照 基于GSM和单片机的远程家电控制系统(毛慧琴)论文编写的的哈 我也是参照她那个自己编写的。目前实现了发短信。
但是我出现了一个情况:就是用CMGS发送短信,TC35i的返回值:
                                          有时只返回了OK,而没有返回+CMGS: <MR>;同样的程序:
                                          有时又可以返回 +CMGS: <MR> 以及OK。
+CMGS: <MR> 和 OK 都返回的短信,对方能成功收到
只返回OK的短信:对方不能收到

今天上午来了,有仔细想了半天。还是没弄明白是怎么回事。还请论坛大虾指导下哈。谢谢

出0入0汤圆

 楼主| 发表于 2011-4-10 10:44:28 | 显示全部楼层
回复【2楼】bangbangji
-----------------------------------------------------------------------
用串口调试助手看了 两种情况发送的源PDU串是相同的。只是TC35i返回的不同:1)、OK   ; 2、+CMGS: <MR> + OK

出0入0汤圆

发表于 2011-4-10 10:52:00 | 显示全部楼层
回复【4楼】jackjie
-----------------------------------------------------------------------

建议你再试试,比如你发送0011000D91685192659365F90008FF325C0A656C76845BA26237FF0C60A876848F668F7D65FA65FA5DF288AB89E653D1FF0C8BF75C3D5FEB524D5F8067E5770BFF01
最后没有换行符,有换行符是发不出去的,但也会返回OK。拷贝上去的代码在串调里发送之前也看看最后有没有换行。

出0入0汤圆

发表于 2011-4-10 11:00:20 | 显示全部楼层
判断短信发送成功请以
"+CMGS:" 字符串为准。

至于你说的那个《毛慧琴》论文,我还没有看见过。可否发上来看看。

出0入0汤圆

发表于 2011-4-10 11:05:54 | 显示全部楼层
【楼主位】 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

出0入0汤圆

 楼主| 发表于 2011-4-10 11:10:22 | 显示全部楼层
回复【5楼】bangbangji
-----------------------------------------------------------------------

刚刚用串口调试助手试了:还是只返回了OK,我将你的然后试的字符串在串口你也试了

0011000D91685122381706F10008FF325C0A656C76845BA26237FF0C60A876848F668F7D65FA65FA5DF288AB89E653D1FF0C8BF75C3D5FEB524D5F8067E5770BFF01


(原文件名:3.jpg)

出0入0汤圆

发表于 2011-4-10 11:11:17 | 显示全部楼层
while ((!bSentSuccessfully) && (++i <= 8))

短信发送并不一定是一次就可以发送成功的,你要学会找AT命令返回值的关键字

出0入0汤圆

 楼主| 发表于 2011-4-10 11:15:32 | 显示全部楼层
回复【9楼】studykaka
-----------------------------------------------------------------------

谢谢你的回复,你的意思是:并不是每次短信都能成功的发送,若果遇到上面只返回OK的情况,就需要我们自己判断出来,再次重新发送,对吗?

出0入0汤圆

发表于 2011-4-10 11:22:44 | 显示全部楼层
【楼主位】 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而不是>

出0入0汤圆

发表于 2011-4-10 11:23:39 | 显示全部楼层
回复【9楼】studykaka  
-----------------------------------------------------------------------

谢谢你的回复,你的意思是:并不是每次短信都能成功的发送,若果遇到上面只返回OK的情况,就需要我们自己判断出来,再次重新发送,对吗?

呵呵,你开悟了

出0入0汤圆

发表于 2011-4-10 11:25:04 | 显示全部楼层
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//针对短信息部分
smsDispatchMessage(void)
{
}

出0入0汤圆

发表于 2011-4-10 11:38:06 | 显示全部楼层
在最后发送短信的过程中,“OK”是没有意义的。

最后只有发送成功,失败,及干拢数据。
所以你要学会解述命令。
懂了这一点,GSM之类的东东可以做到通杀。

出0入0汤圆

 楼主| 发表于 2011-4-10 12:46:27 | 显示全部楼层
回复【14楼】studykaka
-----------------------------------------------------------------------

谢谢你的回复:你的意思我基本已经明白了,就是发送完AT+CMGS = <Len> + <回车后>;判断TC35i的返回值是不是 >,是的话:发送源PDU编码;发送完后,再次检测TC35i有没有返回:+CMGS: <MR> 和 OK (这里主要是检测返回没返回+CMGS:<MR>:若没返回,则继续回到开始从新发送,以确保发送的成功)

还有你说的要毛慧琴的论文,我是nh格式的,上传不了。你要的话留个邮箱。我给你哈

出0入0汤圆

发表于 2011-4-10 12:51:05 | 显示全部楼层
//>,提示发送SMS数据
        else if (strstr((char*)GSM_V1_Receive.GSM_V1_Responses_Receive_Buffer, ">") != NULL)
        {        //表示对卡操作OK
               
        }

07GPS@163.com
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 10:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表