发新帖本帖赏金 36.00元(功能说明)我要提问
返回列表
打印

【原创连载】+和土匪一起玩GPRS模块

[复制链接]
楼主: 我是土匪
手机看帖
扫描二维码
随时随地手机跟帖
81
我是土匪|  楼主 | 2015-9-29 17:40 | 只看该作者 回帖奖励 |倒序浏览
5  AT返回值的解析和URC的处理:
typedefAtcRspType (*AT_cmdHandle)(bool *urc);
typedef struct
{
    char *name;
    AT_cmdHandle atHandle;
}AtcHandleType;
//AT 列表
AtcHandleType  atCmdTable[ ] =
{
        {"ATE",  AtHandle},
        {"AT+CMEE",  AtHandle},
        {"AT+IFC",  AtHandle},
        {"AT+CPIN",   CpinHandle},
        {"AT+CSQ",  CsqHandle}
};
voidDeal_ATCmd(void)
{
    bool urc= TRUE;
    u16 i = 0;


    if (GPRS_SYNC == Gprs_Status)   
    {
        if (NULL != pCurrentCmd)
        {
            for (i = 0; i <sizeof(atCmdTable)/sizeof(atCmdTable[0]); i++)
            {
                if(!strcmp(pCurrentCmd->atName, atCmdTable.name))
                {
                    At_Status =atCmdTable.atHandle(&urc);
                 
                    if (ATC_RSP_FINISH ==At_Status)
                    {
                        pCurrentCmd = NULL;
                    }
                }
            }
        }
        if (urc)
        {
            Deal_URCHandle();
        }
    }
   
}

使用特权

评论回复
82
我是土匪|  楼主 | 2015-9-29 17:42 | 只看该作者
6 通用型AT返回值的处理
AtcRspType AtHandle( bool *urc)
{
   char *Rsp_Str[ ] = {"OK","ERROR"};
   s16  res = -1;
   char *p;
   
   u8  i = 0;
    p= (char *)Rx_Data.buf;

   while ( '\r' == *p || '\n' == *p)
    {
       p++;
    }
   
   for (i = 0; i < sizeof(Rsp_Str) / sizeof(Rsp_Str[0]); i++)
    {
     if (strstr( p,Rsp_Str))
       {
           res = i;
           break;
       }
    }
   *urc = FALSE;
   switch (res)
    {
       case 0:  /* OK */
       {
           At_Status  = ATC_RSP_FINISH;
       }
       break;
        case 1: /* ERROR */
       {
           At_Status = ATC_RSP_FINISH;
       }
       break;
       default:
          *urc = TRUE;
       break;
    }
   return At_Status;
}

使用特权

评论回复
83
我是土匪|  楼主 | 2015-9-29 17:44 | 只看该作者
本帖最后由 我是土匪 于 2015-9-30 11:20 编辑

7 个性化AT返回值解析:CSQ应用举例
AtcRspType CsqHandle( bool *urc)
{
   char *Rsp_Str[ ] = {"OK","ERROR","+CSQ:"};
   s16  res = -1;
   u8 i = 0;
   char *p = (char *)Rx_Data.buf;
   u8 rssi = 0;
   u8 ber = 0;

   while ( '\r' == *p || '\n' == *p)
    {
       p++;
    }


   for (i = 0; i < sizeof(Rsp_Str) / sizeof(Rsp_Str[0]); i++)
    {
      if (strstr( p,Rsp_Str))
       {
           res = i;
           break;
       }
    }


   *urc = FALSE;
   switch (res)
    {
       case 0:  /* OK */
       {
           if(SevrerConnectStatus == FALSE)            
           {
                    if (Csq_Ok)
                         {
                                    //connectto server
                         }
                         else
                         {
                                bsp_StartTimer(CSQ_TIMER_ID,CSQ_TIMERPERIOD, (bspTimerHandler)AT_GetCSQ);

                  }     
                 }

            At_Status  = ATC_RSP_FINISH;
       }
       break;
       case 1:  /* ERROR */
       {
                  bsp_StartTimer(CSQ_TIMER_ID,CSQ_TIMERPERIOD, (bspTimerHandler)AT_GetCSQ);

           At_Status = ATC_RSP_FINISH;

       }     
       break;
       case 2: /* +CSQ: */
       {

           p += strlen("+CSQ:");
           while (' ' == *p)
           {
                p++;
           }

           while (*p >= '0' && *p <= '9')
           {

                       rssi *= 10;
                       rssi += *p++ - '0';
           }

           while ((' '== *p) || (',' == *p))
           {   
                p++;
           }
           while (*p >= '0' && *p <= '9')
           {

                ber *= 10;
                ber += *p++ - '0';

           }


           if (rssi > MIN_CSQ)
           {
                Csq_Ok = TRUE;

           }

       break;
       default:
          *urc = TRUE;
       break;
    }


}
     returnAt_Status;
}

使用特权

评论回复
84
我是土匪|  楼主 | 2015-9-29 17:45 | 只看该作者
8 URC解析框架
void Deal_URCHandle(void)
{
   static char      Closed_count = 0;
   char *p = (char *)Rx_Data.buf;
   s16  urcType = -1;
   u8    i  = 0;
  static char count_pdp = 0;      
   char *UrcTable[ ] = {
                                       "CONNECT OK",
                                        "ALREADYCONNECT",
                                       "CONNECT FAIL",
                                       "SERVER OK",
                                       "SERVER ERROR",
                                       "REMOTE IP:",
                                       "CLOSED",
                                       "+PDP: DEACT",
                                       "+CIPRXGET:1",
                                       "RING",
                                       "NO CARRIER",
                                       "NO DIALTONE",
                                       "BUSY",
                                       "NO ANSWER",
                                       "OK",
                                       "+CPIN: NOT READY"
                                       "+CREG: "
                                       "+CGREG: "
                                    };
           while ('\r' == *p || '\n'== *p)
           {
         p++;
           }
           for (i = 0; i < sizeof(UrcTable)/sizeof(UrcTable[0]); i++)
           {
        if (strstr(p, UrcTable))
        {
                         urcType = i;
                         break;
        }
           }
           switch (urcType)
           {
         case 0: /* CONNECT OK */
              {
   
              }
              break;
              case 1:  /* ALREADY CONNECT */
              {
              }        
              break;
              case 2: /* CONNECT FAIL */
              {
           
              }
              break;
              case 3: /* SERVER OK */
              {
              }
              break;
              case 4:   /* SERVER ERROR */
              {
                 
              }
              break;
              case 5:  /* REMOTE IP: */
              {
              }
              break;
              case 6: /* CLOSED */
              {
      
              }
              break;
              case 7: /* +PDP: DEACT */
              {
           
              
              }
              break;
              case8:    /* +CIPRXGET: 1 */
              {
   
              }
              break;
              case 9: /* RING */
              {
      
              }
              break;
              case 10:  /* NO CARRIER */
              case 11:  /* NO DIALTONE */
              case 12:  /* BUSY */
              case 13:  /* NO ANSWER */
              {
               
              }
              break;
              case 14:  /* OK */
              {
      
              }
              break;
              case15:   //+CPIN: NOT READY
              {
      
              }
              break;
              default:
              break;
           }
   
}

使用特权

评论回复
85
我是土匪|  楼主 | 2015-9-29 17:47 | 只看该作者
9      主函数举例:
void main(void)
{
       PowerOn_Sys();
       Hardware_Init();
       enableInterrupts();
       Param_Init();
        bsp_InitTimer();
        PowerOn_GPRS();      
       while(1)
       {         
             bsp_TimerOutHandler();
              if((GPRS_SYNC== Gprs_Status) && (!Gprs_Init_Flag))
              {
                     GprsCommonAT_Init();//单次执行的任务      
                     /**********************************************************
                     AT执行过程: 入FIFO ->出FIFO,发送给模块 -> 等返回值 ->执行结束
                     AT发送给模块到执行结束这段时间,称之为    ATC_RSP_WAIT,余下过程称为ATC_RSP_FINISH
                    只有在ATC_RSP_FINISH状态下才能发送AT给模块
                     ************************************************************/
                     bsp_StartAutoTimer(AT_TIMER_ID, AT_TIMERPERIOD,(bspTimerHandler)AtcTimerHandle);
                      At_Status =ATC_RSP_FINISH;
                    Gprs_Init_Flag = 1;
        } //RX,判断开机成功与否
        
             if(Rx_Flag)
             {
                  Rx_Flag = 0;
                 
                 Deal_Rx_FromGprs();    //解析AT返回值、URC
             }
    }
}

使用特权

评论回复
86
我是土匪|  楼主 | 2015-9-29 17:48 | 只看该作者
如上代码架构参考了官方的二次开发的例子。
经过测试,可以正常工作。

欢迎交流。

使用特权

评论回复
87
六安飞雨| | 2015-9-29 18:13 | 只看该作者

使用特权

评论回复
88
来与君| | 2015-9-30 00:44 | 只看该作者
楼主上了干货,顶^^^^^^

使用特权

评论回复
89
andy93762| | 2015-10-3 18:19 | 只看该作者
顶下楼主,很精彩

使用特权

评论回复
90
mcumail| | 2015-10-6 09:01 | 只看该作者
占座学习,最近我也在研究sim900A,用的是STC的单片机,主要是发短信,有时成功又时失败

使用特权

评论回复
91
我是土匪|  楼主 | 2015-10-8 09:41 | 只看该作者
mcumail 发表于 2015-10-6 09:01
占座学习,最近我也在研究sim900A,用的是STC的单片机,主要是发短信,有时成功又时失败 ...

要看每条AT的返回值,根据返回值分析。
如果你有多个串口,可以将运行信息打印出来,实时输出,便于分析定位。

使用特权

评论回复
92
我是土匪|  楼主 | 2015-10-10 14:22 | 只看该作者
本帖最后由 我是土匪 于 2015-11-5 13:42 编辑

第四章  DTMF实现远程开门

前言
最近,土匪所在小区改造,所有楼下的门锁变成了电话开门,这让我想起刚刚毕业时进入第一家公司的一段经历:
当时去电力机房安装监控设备,有些很小的独立的机房会在村落旁边或者在庄稼地附近,费尽周折找到一个无人值守的机房,一个小灵通过去,输入几个密码门就打开了。第一次见到这么神奇的高科技,很是惊叹。

今天才知道这里用的是DTMF(dual-tone multifrequency)技术。
想了解DTMF理论,度娘讲解的非常详细,这里不废话。


使用特权

评论回复
93
我是土匪|  楼主 | 2015-10-10 14:27 | 只看该作者
本帖最后由 我是土匪 于 2015-10-10 14:48 编辑

步入正题
如何接收DTMF音?
用GPRS如何做到电话开门?
拿SIM900A为例说明,GPRS实现到电话开门功能,手机拨打拨快,建立语音通信后,手机键盘按键,模块能识别到即为成功。
l        其思路就是被叫方首先使能DTMF侦测功能,之后建立语音通信。
l        再此基础上,主叫方通过电话键盘发送DTMF音,接收方(这里指SIM900A)会通过URC上报DTMF识别的字符。
l        下图为思路:


l         AT操作流程:


使用特权

评论回复
94
我是土匪|  楼主 | 2015-10-10 14:29 | 只看该作者
本帖最后由 我是土匪 于 2015-10-10 14:49 编辑

发送DTMF
参照AT命令:AT+VTS
建立语音通信后,模块通过AT+VTS实现DTMF的发送,比如:
AT+VTS=4
OK
AT+VTS=*
OK
模块发送,手机听筒能听到声音,这就成功了。

使用特权

评论回复
95
我是土匪|  楼主 | 2015-10-10 14:50 | 只看该作者


注意事项:
并不是所有版本都支持DTMF,需要咨询原厂。
DTMF成功率不是100%。出现问题时重复操作即可。

至此,一个包含远程电话开门功能的GPRS部分就完成了,DTMF部分也就结束了。



使用特权

评论回复

打赏榜单

21ic小喇叭 打赏了 5.00 元 2015-10-14

96
zuoxuqi| | 2015-10-19 16:45 | 只看该作者
楼主继续啊

使用特权

评论回复
97
我是土匪|  楼主 | 2015-10-19 16:53 | 只看该作者
本帖最后由 我是土匪 于 2015-10-20 10:34 编辑

;P  以为没有人关注,准备短信部分。

使用特权

评论回复
98
xinyipcb| | 2015-10-19 20:49 | 只看该作者
不错的信息。

使用特权

评论回复
99
JLennon| | 2015-10-20 14:08 | 只看该作者
一直在关注。

使用特权

评论回复
100
来与君| | 2015-10-20 22:59 | 只看该作者
100楼是我的……

使用特权

评论回复
发新帖 本帖赏金 36.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则