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开、关机代码:
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_DELY30
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管控制。
我是土匪
发表于 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
关注一下