我是土匪 发表于 2015-9-29 17:40

5AT返回值的解析和URC的处理:typedefAtcRspType (*AT_cmdHandle)(bool *urc);typedef struct{    char *name;    AT_cmdHandle atHandle;}AtcHandleType;//AT 列表AtcHandleTypeatCmdTable[ ] = {      {"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); i++)            {                if(!strcmp(pCurrentCmd->atName, atCmdTable.name))                {                  At_Status =atCmdTable.atHandle(&urc);                                  if (ATC_RSP_FINISH ==At_Status)                  {                        pCurrentCmd = NULL;                  }                }            }      }       if (urc)      {            Deal_URCHandle();      }    }   }

我是土匪 发表于 2015-9-29 17:42

6 通用型AT返回值的处理AtcRspType AtHandle( bool *urc){   char *Rsp_Str[ ] = {"OK","ERROR"};   s16res = -1;   char *p;       u8i = 0;    p= (char *)Rx_Data.buf;
   while ( '\r' == *p || '\n' == *p)    {       p++;    }       for (i = 0; i < sizeof(Rsp_Str) / sizeof(Rsp_Str); 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;}

我是土匪 发表于 2015-9-29 17:44

本帖最后由 我是土匪 于 2015-9-30 11:20 编辑

7 个性化AT返回值解析:CSQ应用举例AtcRspType CsqHandle( bool *urc){   char *Rsp_Str[ ] = {"OK","ERROR","+CSQ:"};   s16res = -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); 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;}

我是土匪 发表于 2015-9-29 17:45

8 URC解析框架void Deal_URCHandle(void){   static char      Closed_count = 0;   char *p = (char *)Rx_Data.buf;   s16urcType = -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); 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;         }    }

我是土匪 发表于 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             }    } }

我是土匪 发表于 2015-9-29 17:48

如上代码架构参考了官方的二次开发的例子。
经过测试,可以正常工作。

欢迎交流。

六安飞雨 发表于 2015-9-29 18:13

来与君 发表于 2015-9-30 00:44

楼主上了干货,顶^^^^^^

andy93762 发表于 2015-10-3 18:19

顶下楼主,很精彩

mcumail 发表于 2015-10-6 09:01

占座学习,最近我也在研究sim900A,用的是STC的单片机,主要是发短信,有时成功又时失败

我是土匪 发表于 2015-10-8 09:41

mcumail 发表于 2015-10-6 09:01
占座学习,最近我也在研究sim900A,用的是STC的单片机,主要是发短信,有时成功又时失败 ...

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

我是土匪 发表于 2015-10-10 14:22

本帖最后由 我是土匪 于 2015-11-5 13:42 编辑

第四章DTMF实现远程开门
前言最近,土匪所在小区改造,所有楼下的门锁变成了电话开门,这让我想起刚刚毕业时进入第一家公司的一段经历:当时去电力机房安装监控设备,有些很小的独立的机房会在村落旁边或者在庄稼地附近,费尽周折找到一个无人值守的机房,一个小灵通过去,输入几个密码门就打开了。第一次见到这么神奇的高科技,很是惊叹。
今天才知道这里用的是DTMF(dual-tone multifrequency)技术。想了解DTMF理论,度娘讲解的非常详细,这里不废话。

我是土匪 发表于 2015-10-10 14:27

本帖最后由 我是土匪 于 2015-10-10 14:48 编辑

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

l         AT操作流程:

我是土匪 发表于 2015-10-10 14:29

本帖最后由 我是土匪 于 2015-10-10 14:49 编辑

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

我是土匪 发表于 2015-10-10 14:50



注意事项:并不是所有版本都支持DTMF,需要咨询原厂。DTMF成功率不是100%。出现问题时重复操作即可。
至此,一个包含远程电话开门功能的GPRS部分就完成了,DTMF部分也就结束了。


zuoxuqi 发表于 2015-10-19 16:45

楼主继续啊

我是土匪 发表于 2015-10-19 16:53

本帖最后由 我是土匪 于 2015-10-20 10:34 编辑

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

xinyipcb 发表于 2015-10-19 20:49

不错的信息。

JLennon 发表于 2015-10-20 14:08

一直在关注。

来与君 发表于 2015-10-20 22:59

100楼是我的……
页: 1 2 3 4 [5] 6 7 8 9
查看完整版本: 【原创连载】+和土匪一起玩GPRS模块