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

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

[复制链接]
楼主: 我是土匪
手机看帖
扫描二维码
随时随地手机跟帖
justtest111| | 2015-8-28 08:37 | 显示全部楼层
同关注,学习一下。

使用特权

评论回复
datouyuan| | 2015-8-29 11:58 | 显示全部楼层
标记一下,关注中

使用特权

评论回复
kangbidz| | 2015-8-29 16:32 | 显示全部楼层
需要晶振请找康比电子

使用特权

评论回复
forthlab| | 2015-8-30 22:12 | 显示全部楼层
好文,如何收藏啊?

使用特权

评论回复
我是土匪|  楼主 | 2015-8-31 11:09 | 显示全部楼层
本帖最后由 我是土匪 于 2015-9-18 17:17 编辑

更新GPRS开、关机代码:
POWERON.jpg
enum
{
    GPRS_POWERON_STAR = 0,  //拉低POWERKEY开始
    GPRS_POWERON_END ,                 //拉低POWERKEY结束,认为开机动作结束
    GPRS_SYNC,                         //GPRS串口同步成功,成功开机
    GPRS_POWEROFF_STAR,     //开始关机,拉低POWERKEY
    GPRS_POWEROFF_END                //断电
};
#define GPRS_POWERKEY_OUTPUT_LOW()      GPIO_WriteBit(GPRS_POWERKEY_PORT, GPRS_POWERKEY_PIN, SET)
#define GPRS_POWERKEY_OUTPUT_HIGH()     GPIO_WriteBit(GPRS_POWERKEY_PORT, GPRS_POWERKEY_PIN, RESET)

#define GPRS_VBAT_ON()      GPIO_WriteBit(GPRS_POWER_PORT, GPRS_POWER_PIN, SET)
#define GPRS_VBAT_OFF()     GPIO_WriteBit(GPRS_POWER_PORT, GPRS_POWER_PIN, RESET)

#define STATUS_LED_ON()  GPIO_WriteBit(LED_STATUS_PORT, LED_STATUS_PIN,LED_ON)
#define STATUS_LED_OFF()     GPIO_WriteBit(LED_STATUS_PORT, LED_STATUS_PIN,LED_OFF)
#define GPRS_POWER_CTR_EN //使能电源控制
/********************************************
执行开机动作(powerkey)后,发送AT去同步模块串口,最多重复3次,大于3依旧没同步上,证明本次开机失败,或者断电重启或者报警处理等。
发送:AT\r\n
返回:OK\r\n 则表示同步成功
*********************************************/
void Sent_AT(void)
{
    static char count = 0;
    const char AT_cmd[]="AT\r\n";

    if((GPRS_POWERON_STAR == Gprs_Status) || (GPRS_POWERON_END == Gprs_Status))
    {
        count ++;

        if(count > 3)  
            {
            bsp_StopTimer(GPRS_SYNC_TIMER_ID);
            count = 0;
                /*
                本次开机失败,添加自己代码,断电重启,或其他处理
                */
            }
        else
            {
            Sent_String((char *)AT_cmd,strlen(AT_cmd));
            }        
    }
    else
    {
        bsp_StopTimer(GPRS_SYNC_TIMER_ID);
    }
}
/* ----------------------------------------------------------------------------
检测status引脚状态:PD4
1开机
0关机
----------------------------------------------------------------------------- */
char Check_GPRS_StatusPIN(void)
{
   char status = 0;

   status = GPIOD->IDR & GPIO_Pin_4;

   return (status?1:0);
}
/* ----------------------------------------------------------------------------
GPRS关机延时
POWER\断电和状态切换
----------------------------------------------------------------------------- */
void PowerOff_Gprs_Dely(void)
{

    GPRS_POWERKEY_OUTPUT_HIGH();        //POWERKEY PULL UP
    /*断电*/
    #ifdef GPRS_POWER_CTR_EN     
      GPRS_VBAT_OFF();
   #endif
    Gprs_Status = GPRS_POWEROFF_END;
}
/* ----------------------------------------------------------------------------
流程:
GPRS上电->延时200mS->拉低POWERKEY->3S后拉起POWERKEY->5S后AT去同步串口
----------------------------------------------------------------------------- */
volatile char PowerOn_GPRS_Count = 0;
#define POWERON_DELY  30

void PowerOn_GPRS(void)
{
    if((GPRS_POWEROFF_STAR == Gprs_Status) || (GPRS_POWEROFF_END == Gprs_Status))
    {
        bsp_StopTimer(GPRS_POWEROFF_ID); //如果正在关机,停止该进程

        #ifdef GPRS_POWER_CTR_EN
        GPRS_VBAT_ON();//供电
            
        /* 供电需持续一段时间 ,相当于delyMs(200)*/
        PowerOn_GPRS_Count = 0;
        while(PowerOn_GPRS_Count < POWERON_DELY);  //经验值,200ms左右
        #endif                

            
        GPRS_POWERKEY_OUTPUT_LOW();//开始拉低POWERKEY

        //定时3s( >1.2S),定时到拉起POWERKEY
        bsp_StopTimer(POWERKEY_LOW_TIMERID);
        bsp_StartTimer(POWERKEY_LOW_TIMERID, POWERKEY_LOW_TIMERPERIOD, (bspTimerHandler)PullUp_PowerKey);
             //单次执行的定时器

        //定时5S(>3.2S)判断单片机和GPRS模块是否同步成功:         AT
        bsp_StopTimer(GPRS_SYNC_TIMER_ID);
        bsp_StartAutoTimer(GPRS_SYNC_TIMER_ID, GPRS_SYNC_TIMEPERIOD,(bspTimerHandler)Sent_AT);  //周期性的定时器     

        Gprs_Status = GPRS_POWERON_STAR;
            
        //避免串口串电,如果控制电源,有必要这样做。
        #ifdef GPRS_POWER_CTR_EN
             USART_Config();
        #endif
    }           

}
/* ----------------------------------------------------------------------------
关机流程:
拉低POWERKEY ->6S后拉高POWERKEY->断电
(关机拉低1S以上模块会关机,6S左右会彻底关机,此时断电对模块不会造成伤害)
----------------------------------------------------------------------------- */
void PowerOff_GPRS(char cmd)
{
       BitStatus res = 0;

    if((GPRS_POWEROFF_STAR != Gprs_Status) || (GPRS_POWEROFF_END != Gprs_Status))
    {
        //开始拉低POWERKEY
        GPRS_POWERKEY_OUTPUT_LOW();
        Gprs_Status = GPRS_POWEROFF_STAR;
        bsp_StopTimer(GPRS_POWEROFF_ID);
        bsp_StartTimer(GPRS_POWEROFF_ID, POWEROFF_GPRS_TIMERPERIOD, (bspTimerHandler)PowerOff_Gprs_Dely);
    }        
     Led_Cmd = LED_OFF;
}     
/* ----------------------------------------------------------------------------
开机时序中拉起POWERKEY功能
----------------------------------------------------------------------------- */
void PullUp_PowerKey(void)
{
    GPRS_POWERKEY_OUTPUT_HIGH();
    Gprs_Status = GPRS_POWERON_END;
}

   

使用特权

评论回复
我是土匪|  楼主 | 2015-8-31 11:28 | 显示全部楼层
使用举例:
MCU每1分钟进入一次RTC中断,一次开机,一次关机,周而复始,整个开关机过程通过LED指示:
/* ----------------------------------------------------------------------------
外设做初始化
------------------------------------------------------------------------------*/
void Hardware_Init(void)
{
        LED_INIT();
        TIM4_Config();  //作为时间基准
        RTC_Config();
        GPIO_Init(GPRS_POWERKEY_PORT, GPRS_POWERKEY_PIN, GPIO_Mode_Out_PP_Low_Slow);
        GPIO_Init(LED_STATUS_PORT, LED_STATUS_PIN, GPIO_Mode_Out_OD_HiZ_Slow);
        GPIO_Init(LED_STATUS_PORT, LED_STATUS_PIN, GPIO_Mode_Out_OD_HiZ_Slow);

       #ifdef GPRS_POWER_CTR_EN
       GPIO_Init(GPRS_POWER_PORT, GPRS_POWER_PIN, GPIO_Mode_Out_PP_Low_Slow);

      //串口引脚输出0,防止串电。       
       GPIO_Init(GPIOC,GPIO_Pin_2,GPIO_Mode_Out_OD_Low_Slow);
       GPIO_Init(GPIOC,GPIO_Pin_3,GPIO_Mode_Out_OD_Low_Slow);
      #elif
      USART_Config();
     #endif
}

#define WAKEUP_PEROID 60 //60s
void main(void)
{
       static char count = 0;

        PowerOn_Sys();
        Hardware_Init();
        enableInterrupts();

        Param_Init();
        bsp_InitTimer();
         Init_AlarmTime(WAKEUP_PEROID);//60s后触发中断

        while(1)
        {        
              bsp_TimerOutHandler();

              if(Rtc_flag)  //60S一次中断,第一次开机,
             {
                 Rtc_flag = 0;
                 Init_AlarmTime(WAKEUP_PEROID);
                      
                 if(count % 2 == 0)
                    {
                     PowerOff_GPRS();
                    }
                else
                    {
                PowerOn_GPRS();
                       }
                  count ++;
               }
        //RX,判断开机成功与否
          if(Rx_Flag)
          {
                  Rx_Flag = 0;
                  Deal_Rx_FromGprs();
          }
    }

}



使用特权

评论回复
我是土匪|  楼主 | 2015-8-31 11:33 | 显示全部楼层
void Deal_Rx_FromGprs(void)
{
    //下拉POWERKEY过程GPRS可能开机成功
    if((GPRS_POWEROFF_END != Gprs_Status)  || (GPRS_POWEROFF_STAR == Gprs_Status))
    {
            if(strstr((char*)Rx_Data.buf,"OK\r\n"))
                {
                Gprs_Status = GPRS_SYNC;
            Led_Cmd = LED_ON;
                }       
   
    //固定波特率的情况下,开机或模块发生重启时会主动上报RDY
        if(strstr((char*)Rx_Data.buf,"RDY\r\n"))
                {
                Gprs_Status = GPRS_SYNC;
             Led_Cmd = LED_ON;
                }
    }   
        CLear_RxBuf();
}

使用特权

评论回复
我是土匪|  楼主 | 2015-8-31 11:52 | 显示全部楼层
土匪建议:
1、如果模块不需要开关机控制,会简单很多,开机后就不需要再做多余处理。
2、如果模块涉及频繁开关及控制,比如低功耗模式一小时工作一次,最佳方案控制模块电源,关机最后一定要断电,不仅仅是省电,而且稳定。
模块的POWERKEY引脚开机时序和关机时序是相同的,如果判断错误或逻辑错误,开机和关机会颠倒、系统会混乱。而加了电源管理,关机后断电,彻底,放心。
3、如何控制模块电源,如果采用LM2596或者MIC29302这类电源芯片均有电源输出使能引脚,如果LI电池供电,可以考虑直接用MOS管控制。 电源管理.png

使用特权

评论回复

打赏榜单

21ic小喇叭 打赏了 3.00 元 2015-09-07

我是土匪|  楼主 | 2015-8-31 12:03 | 显示全部楼层
本帖最后由 我是土匪 于 2015-8-31 13:55 编辑

周末之前再更新:如何使用AT命令。

使用特权

评论回复
huarana| | 2015-9-1 11:36 | 显示全部楼层
好**,必须支持,

期待大作不断更新。

使用特权

评论回复
叶秋| | 2015-9-2 17:41 | 显示全部楼层
学习一下!

使用特权

评论回复
sfofyyy| | 2015-9-2 21:56 | 显示全部楼层
学习了,期待更新

使用特权

评论回复
guigui| | 2015-9-2 22:14 | 显示全部楼层
土匪大作,赞!

使用特权

评论回复
349264710| | 2015-9-2 23:01 | 显示全部楼层
mark,关注GPRS如何保持实时在线,如何检测各种网络异常并作出反应(如信号不佳,SIM卡未插,服务器端异常)。另外建议楼主提供简单的代码即可,无需用状态机的方式(用状态机逻辑跳跃比较大),毕竟是交流贴,不在代码在于方法。

使用特权

评论回复
zuoxuqi| | 2015-9-3 15:11 | 显示全部楼层
很专业,留个记号继续关注

使用特权

评论回复
我是土匪|  楼主 | 2015-9-3 21:51 | 显示全部楼层
349264710 发表于 2015-9-2 23:01
mark,关注GPRS如何保持实时在线,如何检测各种网络异常并作出反应(如信号不佳,SIM卡未插,服务器端异常) ...

很好的建议。
确实目前数据业务的比重最大。

使用特权

评论回复
崔克七系| | 2015-9-4 21:57 | 显示全部楼层
好帖子搬个小板凳来学习一下

使用特权

评论回复
乐天天| | 2015-9-5 13:54 | 显示全部楼层
我有个朋友在联通上班。他们的流量卡2块多钱一张,哈哈

使用特权

评论回复
我学MCU| | 2015-9-6 09:17 | 显示全部楼层
支持,好**,好内容

使用特权

评论回复
wellhao2004| | 2015-9-6 16:27 | 显示全部楼层
关注一下

使用特权

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

本版积分规则