OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3582|回复: 2

SIM800/SIM900/SIM7000/SIM7600底层操作接口_句柄方式完全分离通信底层

[复制链接]

18

主题

99

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2016-1-20
在线时间
89 小时
发表于 2019-10-31 09:55:54 | 显示全部楼层 |阅读模式
SIM800/SIM900/SIM7000/SIM7600底层操作接口_句柄方式完全分离通信底层

使用SIMCOM公司通信模块将底层的通信与应用完全进行了分离,便于移植。

SIMCOM.h //定义了相关的结构体与类型。

SIMCOM_AT.c//定义了底层的AT接口

SIMCOM_GSM.c//需要的模块GSM相关命令

SIMCOM_GPRS.c//上网相关-未移植

SIMCOM_SMS.c//短信收发相关-未移植

SIMCOM_USER.c//用户最终接口

//需要自己实现数据收发相关接口,DCD,DTR,PWRKEY,STATUS相关IO接口,需要一个ms延时支持


//SIMCOM.h

[url=][/url]
/************************************************************************************************************* * 文件名:            SIMCOM.h * 功能:            SIMCOM 底层定义 * 作者:            cp1300@139.com * 创建时间:        2015-02-15 * 最后修改时间:    2018-03-23 * 详细:            注意:底层通信接口使用的是回调函数,但是必须提供系统延时函数 void SYS_DelayMS(u32 ms);*************************************************************************************************************/#ifndef _SIMCOM_H_#define _SIMCOM_H_#include "system.h"  //SIMCOM通信模块定义    typedef enum{    SIMCOM_SIM900    =    0    ,        //默认为SIM900    SIMCOM_SIM800    =    1    ,        //SIM800    SIMCOM_SIM2000    =    2    ,        //SIM2000    SIMCOM_SIM7600    =    3    ,        //SIM7600    SIMCOM_SIM868    =    4    ,        //SIM868    SIMCOM_SIM7000C    =    5    ,        //SIM7000C    LYNQ_L700        =    10    ,        //LYNQ_L700    SIMCOM_INVALID    =    0XFF    ,    //无效则默认}SIMCOM_MODE_TYPE;     //网络注册状态typedef enum{    SIMCOM_NET_NOT = 0,        //未注册    SIMCOM_NET_YES = 1,        //已经注册    SIMCOM_NET_SEA = 2,        //未注册,正在搜索    SIMCOM_NET_TUR = 3,        //注册被拒绝    SIMCOM_NET_UNK = 4,        //未知    SIMCOM_NET_ROA = 5,        //已经注册,但是漫游    SIMCOM_NET_ERROR=0XFF    //错误}SIMCOM_NETSTATUS;   //SIMCOM网络制式typedef enum{    SIMCOM_NETMODE_NOT             =     0,    //未注册    SIMCOM_NETMODE_GSM            =    1,    //GSM    SIMCOM_NETMODE_GPRS            =    2,    //GPRS    SIMCOM_NETMODE_EGPRS        =    3,    //EGPRS (EDGE)    SIMCOM_NETMODE_WCDMA        =    4,    //WCDMA    SIMCOM_NETMODE_HSDPA        =    5,    //HSDPA only(WCDMA)    SIMCOM_NETMODE_HSUPA        =    6,    //HSUPA only(WCDMA)    SIMCOM_NETMODE_HSPA            =    7,    //HSPA (HSDPA and HSUPA, WCDMA)    SIMCOM_NETMODE_LTE            =    8,    //LTE    SIMCOM_NETMODE_TDS_CDMA        =    9,    //TDS-CDMA    SIMCOM_NETMODE_TDS_HSDPA    =    10,    //TDS-HSDPA only(SIM7000C 电信NB也是这个)    SIMCOM_NETMODE_TDS_HSUPA    =    11,    //TDS-HSUPA only    SIMCOM_NETMODE_TDS_HSPA        =    12,    //TDS- HSPA (HSDPA and HSUPA)    SIMCOM_NETMODE_CDMA            =    13,    //CDMA    SIMCOM_NETMODE_EVDO            =    14,    //EVDO    SIMCOM_NETMODE_HYBRID        =    15,    //HYBRID (CDMA and EVDO)    SIMCOM_NETMODE_1XLTE        =    16,    //1XLTE(CDMA and LTE)    SIMCOM_NETMODE_NULL            =    0xff,    //未知}SIMCOM_NETMODE_TYPE;  //SIM卡就绪状态typedef enum{    SIM_READY            =    0,    //SIM卡就绪    SIM_NOT_READY        =    1,    //SIM卡未就绪    SIM_UNKNOWN            =    2    //SIM卡状态未知}SIM_CARD_STATUS; //控制IO电平定义#define SIMCOM_H_LEVEL        1    //高电平#define SIMCOM_L_LEVEL        0    //低电平 //DCD状态定义#define DCD_DATA_MODE        0    //数据透传模式#define DCD_AT_MODE            1    //AT指令模式 //相关信息长度限制#define SIMCOM_INFO_SIZE    24    //信息长度#define SIMCOM_VER_SIZE        24    //软件版本长度定义 //重试次数,防止AT指令操作失败#define SIMCOM_DEFAULT_RETRY    2   //SIMCOM模块相关信息typedef struct{    char Manu[SIMCOM_INFO_SIZE+1];                    //制造商    char Model[SIMCOM_INFO_SIZE+1];                    //型号    char Ver[SIMCOM_VER_SIZE+1];                    //软件版本    char IMEI[SIMCOM_INFO_SIZE+1];                    //序列号}SIMCOM_INFO;  //NBIOT模式定义typedef enum{    NB_IOT_MODE = 0,        //NBIOT模式    CAT_M_MODE = 1,            //CAT-M模式}NBIOT_MODE_TYPE; //网络模式设置typedef struct{    SIMCOM_MODE_TYPE    ModeType;                    //模块型号    NBIOT_MODE_TYPE     NB_Mode;                    //NB模式    s8 NB_EnableMode;                                //NB模式使能模式,-1:无需设置;0:关闭NB,使能GSM模式;1:使能NB模式    bool isNB_ScarEnable;                            //NB模式扰码使能}NETWORK_CONFIG_TYPE;   //SIMCOM通信模块句柄typedef struct{    //所需变量    SIMCOM_MODE_TYPE    SimcomModeType;                //模块型号    char TelecomCarr[SIMCOM_INFO_SIZE+1];            //运营商名称    SIMCOM_INFO SIMCOM_Info;                        //SIMCOM通信模块相关信息结构体    NETWORK_CONFIG_TYPE NetworkConfig;                //网络模式设置    SIMCOM_NETMODE_TYPE NetworkMode;                //当前网络制式    u8 Singal;                                        //网络信号强度    char LocalPhoneNumber[16];                        //本机电话号码    char ServiceCenterPhoneNumber[16];                //短信中心电话号码    char SIM_CIMI[16];                                //SIM卡唯一CIMI号码            //底层通信接口    bool (* pSendData)(u8 *pDataBuff, u16 DataLen);                                            //发送数据接口,如果发送失败,返回FALSE,成功返回TRUE;    int (* pReadData)(u8 **pDataBuff, u8 ByteTimeOutMs, u16 TimeOutMs, u16 *pReceiveDelay);    //接收数据接口,返回数据长度,如果失败返回<=0,成功,返回数据长度    void (*pClearRxData)(void);                                                                //清除接收缓冲区函数,用于清除接收数据缓冲区数据    void (*pSetDTR_Pin)(u8 Level);                                                            //DTR引脚电平控制-用于控制sleep模式或者退出透传模式    void (*pSetPWRKEY_Pin)(u8 Level);                                                        //PWRKEY开机引脚电平控制-用于开机    u8 (*pGetSTATUS_Pin)(void);                                                                //获取STATUS引脚电平-用于指示模块上电状态    u8 (*pGetDCD_Pin)(void);                                                                //获取DCD引脚电平-高电平AT指令模式,低电平为透传模式    //系统接口    void (*pDelayMS)(u32 ms);                                                                //系统延时函数    void (*pIWDG_Feed)(void);                                                                //清除系统看门狗(可以为空)    //内部状态定义    bool s_isInitStatus;                                                                    //用于记录模块初始化状态,复位或上电后变为无效}SIMCOM_HANDLE;   #endif /*_SIMCOM_H_*/[url=][/url]

//SIMCOM_AT.c
[url=][/url]
/************************************************************************************************************* * 文件名:            SIMCOM_AT.c * 功能:            SIMCOM底层AT指令接口 * 作者:            cp1300@139.com * 创建时间:        2015-02-15 * 最后修改时间:    2018-03-23 * 详细:            *************************************************************************************************************/#include "system.h"#include "usart.h"#include "SIMCOM_AT.h"#include "SIMCOM.h"#include "string.h"#include "ucos_ii.h" bool g_SIMC0M_AT_Debug = TRUE;    //底层AT指令调试状态 //调试开关#define SIMCOM_DBUG        1#if SIMCOM_DBUG    #include "system.h"    #define SIMCOM_debug(format,...)    {if(g_SIMC0M_AT_Debug){uart_printf(format,##__VA_ARGS__);}}#else    #define SIMCOM_debug(format,...)    /\/#endif    //SIMCOM_DBUG  /************************************************************************************************************************** 函数                :    bool SIMCOM_SendAT(SIMCOM_HANDLE *pHandle, char *pStr)* 功能                :    发送一个AT指令(会添加结束符\r\n),不会等待响应* 参数                :    pHandle:SIMCOM句柄;pStr:指令字符串* 返回                :    接口发送状态* 依赖                :    无* 作者                :    cp1300@139.com* 时间                :    2018-03-23* 最后修改时间         :     2018-03-23* 说明                :     用于底层AT指令发送*************************************************************************************************************************/bool SIMCOM_SendAT(SIMCOM_HANDLE *pHandle, char *pStr){    pHandle->pSendData((u8 *)pStr, strlen(pStr));    //发送指令    return pHandle->pSendData((u8 *)"\r\n", 2);        //发送结束符}     /************************************************************************************************************************** 函数            :    bool SIMCOM_TestAT(SIMCOM_HANDLE *pHandle, u32 retry)* 功能            :    SIMCOM AT 命令通信测试* 参数            :    pHandle:SIMCOM句柄;retry:重试次数* 返回            :    FALSE:通信失败;TRUE:通信成功* 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2013-10-20* 最后修改时间 :     2018-03-23* 说明            :     每隔100ms向SIMCOM通信模块发送一个"AT",等待响应返回*************************************************************************************************************************/bool SIMCOM_TestAT(SIMCOM_HANDLE *pHandle, u32 retry){    u32 cnt;    u8 *pRxBuff;        //检测模块存在    do    {        SIMCOM_SendAT(pHandle, "AT");                                                            //发送"AT",同步波特率,并且等待应答        pHandle->pClearRxData();                                                                //清除计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pRxBuff, &cnt, "OK", 10, 150))            //等待响应,超时150ms        {            pHandle->pDelayMS(100);            return TRUE;        }        retry --;    }while(retry);        pHandle->pDelayMS(100);    return FALSE;}  /************************************************************************************************************************** 函数                :    bool SIMCOM_WaitSleep(SIMCOM_HANDLE *pHandle, u32 TimeOutMs)* 功能                :    等待模块空闲,并重新唤醒* 参数                :    pHandle:句柄;TimeOut:等待超时,时间单位ms* 返回                :    TRUE:成功;FALSE:超时* 依赖                :    无* 作者                :    cp1300@139.com* 时间                :    2013-10-25* 最后修改时间         :     2018-03-24* 说明                :     用于等待操作完成,防止快速操作造成模块不响应*************************************************************************************************************************/bool SIMCOM_WaitSleep(SIMCOM_HANDLE *pHandle, u32 TimeOutMs){    u32 i;    u32 cnt;    u8 *pData;        if(TimeOutMs < 100) TimeOutMs = 100;        //最少100ms    pHandle->pSetDTR_Pin(SIMCOM_H_LEVEL);        //等待模块空闲后进入SLEEP模式        //循环发送命令,直到命令超时了则认为进入了sleep模式    for(i = 0;i < (TimeOutMs/100);i ++)    {        pHandle->pDelayMS(100);            //延时100ms        SIMCOM_SendAT(pHandle, "AT");            //发送"AT",同步波特率,并且等待应答        pHandle->pClearRxData();                //清除接收计数器        if(AT_RETURN_TIME_OUT == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 100))    //等待响应,超时100ms        {            break;        }    }    pHandle->pSetDTR_Pin(SIMCOM_L_LEVEL);        //唤醒        if(i == (TimeOutMs/100))     {        SIMCOM_debug("模块进入空闲模式失败!\r\n");        pHandle->pClearRxData();                //清除接收计数器                return FALSE;    }    pHandle->pDelayMS(100);                //延时100ms        SIMCOM_debug("模块进入空闲模式成功!\r\n");    SIMCOM_TestAT(pHandle, 10);    pHandle->pClearRxData();                //清除接收计数器        return TRUE;}       /************************************************************************************************************************** 函数                :    SIMCOM_AT_ERROR SIMCOM_GetATResp(SIMCOM_HANDLE *pHandle, u8 **pRxBuff, u32 *pLen, const char *pKeyword, u8 ByteTimeOutMs, u16 TimeOutMs)* 功能                :    获取SIMCOM的AT指令响应* 参数                :    pHandle:句柄                        pRxBuff:接收缓冲区指针(输出);pLen:接收到的数据大小(输出),                        pKeyword:关键字,为字符串,比如"OK",如果在接收到的字符串中有OK字符,就返回成功,否则失败(输入)                        ByteTimeOutMs:字节超时时间,单位ms最大255ms                        TimeOutMs:等待超时时间,单位毫秒* 返回                :    SIM900_ERROR* 依赖                :    无* 作者                :    cp1300@139.com* 时间                :    2018-03-24* 最后修改时间         :     2018-03-24* 说明                :     本函数会在接收缓冲区字符串结束添加'\0'                        本函数不能清除缓冲区*************************************************************************************************************************/SIMCOM_AT_ERROR SIMCOM_GetATResp(SIMCOM_HANDLE *pHandle, u8 **pRxBuff, u32 *pLen, const char *pKeyword, u8 ByteTimeOutMs, u16 TimeOutMs){    int len;    u16 ReceiveDelay;     if(ByteTimeOutMs < 1) ByteTimeOutMs = 1;    len = pHandle->pReadData(pRxBuff, ByteTimeOutMs, TimeOutMs, &ReceiveDelay);    //调用回调接口,读取数据    //等待超时    if(len == 0)    {        return AT_RETURN_TIME_OUT;                                                //返回超时错误    }    //数据接收完毕    *pLen = len;                                                                //返回接收数据长度    if((*pRxBuff)[len-1] != 0)    {        (*pRxBuff)[len]    = '\0';                                                    //将数据结尾添加结束字符串    }        SIMCOM_debug("\r\nSIMCOM(%dB)->%s\r\n",len, *pRxBuff);                        //打印返回信息    if(strstr((const char*)(*pRxBuff), pKeyword) != NULL)     //搜索关键字    {        SIMCOM_debug("%s 返回成功!\r\n",pKeyword);        return AT_RETURN_OK;    }    else if(strstr((const char*)(*pRxBuff), "ERROR") != NULL)    {        SIMCOM_debug("%s 返回错误!\r\n",pKeyword);        return AT_RETURN_ERROR;    }    else    {        SIMCOM_debug("%s 返回未知!\r\n",pKeyword);        return AT_RETURN_UNKNOWN;    }}    /************************************************************************************************************************** 函数                :    bool SIM900_SetParametersReturnBool(char *pATCom, u8 retry, u16 TimeOutx10MS, const char *pErrorDebug)* 功能                :    设置SIM900一个参数,返回一个bool状态* 参数                :    pATCom:AT命令;retry:重试次数;TimeOut:命令超时时间,单位10ms;pErrorDebug:失败后提示的调试信息* 返回                :    TRUE:执行成功了,返回了OK,FALSE:执行失败了,返回了ERROR或其它* 依赖                :    SIM900* 作者                :    cp1300@139.com* 时间                :    2014-12-19* 最后修改时间     :     2014-12-19* 说明                :     用于简化命名发送,防止代码重复*************************************************************************************************************************/bool SIMCOM_SetParametersReturnBool(SIMCOM_HANDLE *pHandle, char *pATCom, u8 retry, u16 TimeOutMs, const char *pErrorDebug){    u32 cnt;    u8 *pData;                retry += 1;        //重试次数    do    {            SIMCOM_SendAT(pHandle,pATCom);            //发送AT命令        pHandle->pClearRxData();                //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, TimeOutMs))    //等待响应,超时10s        {            pHandle->pClearRxData();            //清除接收计数器            return TRUE;        }                SIMCOM_Ready(pHandle);                    //等待就绪        retry --;    }while(retry);        if(pErrorDebug!=NULL)     {        uart_printf("%s",pErrorDebug);            //输出调试信息    }    pHandle->pClearRxData();                    //清除接收计数器        return FALSE;}    /**************************************************************************************************************************函数            :    u32 GSM_StringToHex(char *pStr, u8 NumDigits)*功能            :    将16进制样式字符串转换为16进制整型数(必须保证字符串字母都是大写)*参数            :    pStr:字符串起始指针*                     NumDigits:数字位数,16进制数字位数*返回            :    转换后的数字*依赖            :    无*作者            :    cp1300@139.com*时间            :    2013-04-30*最后修改时间    :    2013-10-17*说明            :    比如字符串"A865"转换后为0xA865,位数为4位                    必须保证字符串字母都是大写*************************************************************************************************************************/u32 GSM_StringToHex(char *pStr, u8 NumDigits){    u8 temp;    u32 HEX = 0;    u8 i;        NumDigits = (NumDigits > 8) ? 8 : NumDigits;    //最大支持8位16进制数        for(i = 0;i < NumDigits;i ++)    {        HEX <<= 4;        temp = pStr;        temp = (temp > '9') ? temp - 'A' + 10 : temp - '0';        HEX |= temp;    }    return HEX;}  /**************************************************************************************************************************函数            :    void GSM_HexToString(u32 HexNum,c har *pStr, u8 NumDigits)*功能            :    将整型数字转换为16进制样式字符串(字母为大写,不带结束符)*参数            :    HexNum:16进制数字                    pStr:字符缓冲区指针*                     NumDigits:数字位数,16进制数字位数*返回            :    无*依赖            :    无*作者            :    cp1300@139.com*时间            :    2013-04-30*最后修改时间    :    2013-04-30*说明            :    比如字符串0xA865转换后为"A865",位数为4位*************************************************************************************************************************/void GSM_HexToString(u32 HexNum,char *pStr, u8 NumDigits){    u8 temp;    u8 i;        NumDigits = (NumDigits > 8) ? 8 : NumDigits;    //最大支持8位16进制数        for(i = 0;i < NumDigits;i ++)    {        temp = 0x0f & (HexNum >> (4 * (NumDigits - 1 - i)));        temp = (temp > 0x09) ? (temp - 0x0A + 'A') : (temp + '0');        pStr = temp;    }}    /**************************************************************************************************************************函数            :    u32 GSM_StringToDec(char *pStr, u8 NumDigits)*功能            :    将10进制样式字符串转换为整型数(必须保证完全为数字字符)*参数            :    pStr:字符串起始指针*                     NumDigits:数字位数,10进制数字位数*返回            :    转换后的数字*依赖            :    无*作者            :    cp1300@139.com*时间            :    2013-04-30*最后修改时间    :    2013-04-30*说明            :    比如字符串"1865"转换后为1865,位数为4位                    必须保证完全为数字字符*************************************************************************************************************************/u32 GSM_StringToDec(char *pStr, u8 NumDigits){    u32 temp;    u32 DEC = 0;    u8 i;    u8 j;        NumDigits = (NumDigits > 10) ? 10 : NumDigits;    //最大支持10位10进制数        for(i = 0;i < NumDigits;i ++)    {        temp = pStr - '0';        if(temp > 9)            //只能是数字范围            return 0;        for(j = 1;j < (NumDigits - i);j ++)        {            temp *= 10;        }        DEC += temp;    }    return DEC;}[url=][/url]

//SIMCOM_AT.h
[url=][/url]
/************************************************************************************************************* * 文件名:            SIMCOM_AT.h * 功能:            SIMCOM底层AT指令接口 * 作者:            cp1300@139.com * 创建时间:        2015-02-15 * 最后修改时间:    2018-03-23 * 详细:            *************************************************************************************************************/#ifndef _SIMCOM_AT_H_#define _SIMCOM_AT_H_#include "system.h"#include "SIMCOM.h" extern bool g_SIMC0M_AT_Debug;    //底层AT指令调试状态   //SIM900返回错误typedef enum{    AT_RETURN_OK            =        0,        //返回成功    AT_RETURN_ERROR            =        1,        //返回错误    AT_RETURN_UNKNOWN        =        2,        //返回结果未知    AT_RETURN_TIME_OUT        =        0xf,    //等待返回超时}SIMCOM_AT_ERROR;    //相关接口bool SIMCOM_SendAT(SIMCOM_HANDLE *pHandle, char *pStr);                                                                                        //发送一个AT指令(会添加结束符\r\n),不会等待响应SIMCOM_AT_ERROR SIMCOM_GetATResp(SIMCOM_HANDLE *pHandle, u8 **pRxBuff, u32 *pLen, const char *pKeyword, u8 ByteTimeOutMs, u16 TimeOutMs);    //获取SIMCOM的AT指令响应bool SIMCOM_SendAT(SIMCOM_HANDLE *pHandle, char *pStr);                                                                                        //发送一个AT指令(会添加结束符\r\n),不会等待响应bool SIMCOM_WaitSleep(SIMCOM_HANDLE *pHandle, u32 TimeOutMs);                                                                                //等待模块空闲,并重新唤醒bool SIMCOM_TestAT(SIMCOM_HANDLE *pHandle, u32 retry);                                                                                        //SIMCOM AT 命令通信测试#define SIMCOM_Ready(pHandle)  if(SIMCOM_TestAT(pHandle, 5) == FALSE){SIMCOM_WaitSleep(pHandle, 1000);}                                        //让SIMCOM就绪,防止卡住//串口同步失败,等待上一个操作完成bool SIMCOM_SetParametersReturnBool(SIMCOM_HANDLE *pHandle, char *pATCom, u8 retry, u16 TimeOutMs, const char *pErrorDebug);                //设置SIM900一个参数,返回一个bool状态   //通用工具u32 GSM_StringToHex(char *pStr, u8 NumDigits);                //将16进制样式字符串转换为16进制整型数(必须保证字符串字母都是大写)u32 GSM_StringToDec(char *pStr, u8 NumDigits);                //将10进制样式字符串转换为整型数(必须保证完全为数字字符)void GSM_HexToString(u32 HexNum,char *pStr, u8 NumDigits);    //将整型数字转换为16进制样式字符串(字母为大写,不带结束符) #endif /*SIMCOM_AT*/[url=][/url]

//SIMCOM_GSM.c //通用的底层操作
[url=][/url]
/************************************************************************************************************* * 文件名:            SIMCOM_GSM.c * 功能:            SIMCOM GSM相关接口 * 作者:            cp1300@139.com * 创建时间:        2015-02-15 * 最后修改时间:    2018-03-23 * 详细:            *************************************************************************************************************/#include "system.h"#include "usart.h"#include "SIMCOM_GSM.h"#include "SIMCOM_AT.h"#include "string.h"#include "SIMCOM.h"#include <stdlib.h> bool g_SIMC0M_GSM_Debug = TRUE;    //底层AT指令调试状态 //调试开关#define SIMCOM_GSM_DBUG        1#if SIMCOM_GSM_DBUG    #include "system.h"    #define SIMCOM_GSM_debug(format,...)    {if(g_SIMC0M_GSM_Debug){uart_printf(format,##__VA_ARGS__);}}#else    #define SIMCOM_GSM_debug(format,...)    /\/#endif    //SIMCOM_GSM_DBUG    /************************************************************************************************************************** 函数            :    bool SIMCOM_NetworkConfig(SIMCOM_HANDLE *pHandle, SIMCOM_MODE_TYPE ModeType, SIMCOM_SIM_SELECT SIM_Select)* 功能            :    SIMCOM网络配置* 参数            :    pHandle:句柄;ModeType:通信模块型号;SIM_Select:SIM卡选择;* 返回            :    TRUE:成功,FALSE:失败    * 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2018-01-17* 最后修改时间    :     2018-03-24 * 详细            :*************************************************************************************************************************/ bool SIMCOM_NetworkConfig(SIMCOM_HANDLE *pHandle, SIMCOM_MODE_TYPE ModeType, NETWORK_CONFIG_TYPE *pConfig)    {    char buff[16];        pConfig->ModeType = ModeType;                    //记录通信模块型号    if(ModeType == SIMCOM_SIM7000C)                    //SIM7000C需要选择工作模式    {            switch(pConfig->NB_EnableMode)        {            case 0: //GSM模式            {                uart_printf("[DTU]设置GSM网络模式!\r\n");                if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CNMP=13", SIMCOM_DEFAULT_RETRY, 200, "\r\n设置SIM7000C GSM模式失败!\r\n") == FALSE) return FALSE; //GSM模式            }break;            case 1://NB模式            {                uart_printf("[DTU]设置NBIOT网络模式!\r\n");                if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CNMP=38", SIMCOM_DEFAULT_RETRY, 200, "\r\n设置SIM7000C LTE NB模式失败!\r\n") == FALSE) return FALSE; //LTE only(使用NB-IOT网络时CNMP需要设置为38)                //CAT NB模式设置                switch(pConfig->ModeType)                {                    case CAT_M_MODE: //CAT模式                    {                        sprintf(buff,"AT+CMNB=%d",1); //cat模式                    }break;                    default:                     {                        sprintf(buff,"AT+CMNB=%d",2); //NBIOT模式                    }break;                }                if(SIMCOM_SetParametersReturnBool(pHandle, buff, SIMCOM_DEFAULT_RETRY, 200, "\r\n设置SIM7000C CAT NB模式失败!\r\n") == FALSE) return FALSE; //1: CAT-M 2: NB-IOT                //扰码设置                if(pConfig->isNB_ScarEnable) //开启扰码                {                    sprintf(buff,"AT+NBSC=%d",1);                 }                else                {                    sprintf(buff,"AT+NBSC=%d",0);                 }                if(SIMCOM_SetParametersReturnBool(pHandle, buff, SIMCOM_DEFAULT_RETRY, 200, "\r\n设置SIM7000C NB 扰码模式失败!\r\n") == FALSE) return FALSE;             }break;            default:return TRUE;                    //忽略,无需设置        }    }    return TRUE;}    /************************************************************************************************************************** 函数                :    SIM_CARD_STATUS SIMCOM_GetCPIN(SIMCOM_HANDLE *pHandle)* 功能                :    获取SIM卡状态* 参数                :    无* 返回                :    FALSE:失败;TRUE:成功* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2014-06-26* 最后修改时间         :     2014-06-26* 说明                :     2017-09-05 : 增加SIM卡状态为3种状态*************************************************************************************************************************/SIM_CARD_STATUS SIMCOM_GetCPIN(SIMCOM_HANDLE *pHandle){    u32 cnt;    char *p;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    int status;    u8 *pData;        do    {            //+CPIN: READY        SIMCOM_SendAT(pHandle, "AT+CPIN?");                                                    pHandle->pClearRxData();                                                //清除接收计数器        status = SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 20, 200);        //等待响应,超时200MS        if(AT_RETURN_OK == status)                                                //返回OK        {            p = strstr((const char*)pData, "+CPIN: READY");                        //搜索字符"+CPIN: READY"            if(p != NULL)                                                         //搜索成功            {                return SIM_READY;                                                //SIM卡就绪            }            break;        }        else if(AT_RETURN_ERROR == status)                                        //返回ERROR        {            p = strstr((const char*)pData, "ERROR");                            //搜索卡未准备就绪标志            if(p != NULL)                                                         //搜索成功            {                return SIM_NOT_READY;                                            //SIM卡未就绪            }            break;        }                SIMCOM_Ready(pHandle);                                                    //等待就绪        pHandle->pDelayMS(1000);                                                //失败延时1秒后重试        retry --;    }while(retry);        return SIM_UNKNOWN;                                                            //SIM卡未知}   /************************************************************************************************************************** 函数                :    SIMCOM_NETSTATUS SIM900_GetGSMNetworkStatus(SIMCOM_HANDLE *pHandle)* 功能                :    获取GSM网络注册状态* 参数                :    pHandle:句柄* 返回                :    SIMCOM_NETSTATUS* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2013-10-29* 最后修改时间         :     2018-03-24* 说明                :     当网络注册后,可能被拒绝,如果被拒绝,获取网络注册状态会提示                        注册成功的,但是通过发送AT 后再去查询,会发现网络注册失败*************************************************************************************************************************/SIMCOM_NETSTATUS SIM900_GetGSMNetworkStatus(SIMCOM_HANDLE *pHandle){    u32 cnt;    char *p;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;        do    {            //+CREG: 0,1        SIMCOM_SendAT(pHandle, "AT+CREG?");                                            //发送"AT+CREG?",获取网络注册状态        pHandle->pClearRxData();                                                    //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 20, 200))    //等待响应,超时200MS        {            p = strstr((const char*)pData, "+CREG:");                                //搜索字符"+CREG:"            if(p != NULL)                                                             //搜索成功            {                SIMCOM_TestAT(pHandle, 1);                return (SIMCOM_NETSTATUS)GSM_StringToDec(&p[9], 1);            }            break;        }                SIMCOM_Ready(pHandle);                                                        //等待就绪        pHandle->pDelayMS(1000);                                                    //失败延时1秒后重试        retry --;    }while(retry);        SIMCOM_TestAT(pHandle, 2);    return SIMCOM_NET_ERROR;}    /************************************************************************************************************************** 函数                :    SIMCOM_NETSTATUS SIMCOM_GetDataNetworkStatus(SIMCOM_HANDLE *pHandle)* 功能                :    获取数据网络注册状态* 参数                :    pHandle:句柄* 返回                :    SIMCOM_NETSTATUS* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2013-10-29* 最后修改时间         :     2018-03-24* 说明                :     用于获取NB数据网络或GPRS数据网络注册状态*************************************************************************************************************************/SIMCOM_NETSTATUS SIMCOM_GetDataNetworkStatus(SIMCOM_HANDLE *pHandle){    u32 cnt;    char *p;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;        do    {            //+CGREG: 0,1        SIMCOM_SendAT(pHandle, "AT+CGREG?");                                        //发送"AT+CGREG?",获取网络注册状态        pHandle->pClearRxData();                                                    //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 20, 200))    //等待响应,超时200MS        {            p = strstr((const char*)pData, "+CGREG:");                                //搜索字符"+CGREG:"            if(p != NULL)                                                             //搜索成功            {                SIMCOM_TestAT(pHandle, 1);                return (SIMCOM_NETSTATUS)GSM_StringToDec(&p[10], 1);            }            break;        }                SIMCOM_Ready(pHandle);                                                        //等待就绪        pHandle->pDelayMS(1000);                                                    //失败延时1秒后重试        retry --;    }while(retry);        SIMCOM_TestAT(pHandle, 2);    return SIMCOM_NET_ERROR;}   /************************************************************************************************************************** 函数                :    bool SIM900_SetGPRS_PackDatatSize(SIMCOM_HANDLE *pHandle)* 功能                :    设置SIM900/SIM800 GPRS发送数据缓冲区* 参数                :    pHandle:句柄* 返回                :    FALSE:失败;TRUE:成功* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2014-09-11* 最后修改时间         :     2014-09-11* 说明                :     按照最大数据包1460B设置*************************************************************************************************************************/bool SIM900_SetGPRS_PackDatatSize(SIMCOM_HANDLE *pHandle){    char buff[36];     //先开启透传模式才能设置    SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPMODE=1", SIMCOM_DEFAULT_RETRY, 2000, "开启透传模式失败!\r\n");    //开启透传模式        //设置GPRS传输数据包大小    //AT+CIPCCFG=3,2,1024,1 //设置透传参数 //3-重传次数为3次,2-等待数据输入时间为 //2*200ms,1024-数据缓冲区为1024个字节 //1-支持转义退出透传    sprintf(buff,"AT+CIPCCFG=3,2,%d,1",1460);    return SIMCOM_SetParametersReturnBool(pHandle, buff, SIMCOM_DEFAULT_RETRY, 200, "GPRS发送数据缓冲区设置失败!\r\n");    //发送    }   /************************************************************************************************************************** 函数                :    bool SIMCOM_ModuleInit(SIMCOM_HANDLE *pHandle)* 功能                :    初始化SIMCOM模块基本配置(不允许失败)* 参数                :    pHandle:句柄* 返回                :    FALSE:初始化失败;TRUE:初始化成功* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2013-10-16* 最后修改时间         :     2018-03-24* 说明                :     必须先上电,并获取模块型号,根据不同的型号模块分别进行初始化*************************************************************************************************************************/bool SIMCOM_ModuleInit(SIMCOM_HANDLE *pHandle){    u8 retry = 5;                            //重试次数        pHandle->pSetDTR_Pin(SIMCOM_L_LEVEL);    //DTR=0,退出低功耗模式    //检测模块存在,并保证通信正常    SIMCOM_Ready(pHandle);    SIMCOM_TestAT(pHandle, 20);        switch(pHandle->SimcomModeType)            //不同的芯片存在不一样的初始化    {        case SIMCOM_SIM2000:                //SIM2000需要先关闭URC,否则会提示Call Ready        {            SIMCOM_SetParametersReturnBool(pHandle, "AT+CIURC=0", SIMCOM_DEFAULT_RETRY, 110, "\r\n关闭Call Ready显示失败!\r\n");        }break;        default:break;    }    //设置关闭回显    if(SIMCOM_SetParametersReturnBool(pHandle, "ATE 0", SIMCOM_DEFAULT_RETRY, 110, "\r\n关闭AT回显模式失败!\r\n") == FALSE)    {        return FALSE;    }    //设置短消息格式为PDU格式    if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CMGF=0", SIMCOM_DEFAULT_RETRY, 110, "\r\n设置短消息格式为PDU格式失败!\r\n") == FALSE)    {        uart_printf("\r\n设置DCD功能模式失败!\r\n");        return FALSE;    }    //设置DCD功能模式,DCD线只在数据载波存在时为ON。    if(SIMCOM_SetParametersReturnBool(pHandle, "AT&C1", SIMCOM_DEFAULT_RETRY, 110, "\r\n设置DCD功能模式失败!\r\n") == FALSE)    {        uart_printf("\r\n设置DCD功能模式失败!\r\n");        //return FALSE;    }    //设置 DTR 功能模式,DTR 由ON至OFF:TA在保持当前数据通话的同时,切换至命令模式    if(SIMCOM_SetParametersReturnBool(pHandle, "AT&D1", SIMCOM_DEFAULT_RETRY, 110, "\r\n设置DTR功能模式失败!\r\n") == FALSE)    {        uart_printf("\r\n设置DTR功能模式失败!\r\n");        //return FALSE;    }    //    //使能RI引脚提示//    if(SIM900_SetParametersReturnBool("AT+CFGRI=1", SIMCOM_DEFAULT_RETRY, 11, "\r\n启动RI引脚提示失败!\r\n") == FALSE)//    {//        return FALSE;//    }        //设置模块sleep模式使能//发送"AT+CSCLK",启动SLEEP模式;0:关闭;1:手动;2:自动空闲5S钟后休眠    if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CSCLK=1", SIMCOM_DEFAULT_RETRY, 110, "\r\n设置SLEEP失败!\r\n") == FALSE)    {        return FALSE;    }          //检查卡是否就绪    retry = 8;                    //重试次数    do    {        if(SIMCOM_GetCPIN(pHandle)==SIM_READY)        {            uart_printf("\r\nSIM卡准备就绪!\r\n");            break;        }        else        {            uart_printf("\r\nSIM卡未准备就绪!\r\n");        }                SIMCOM_Ready(pHandle);                        //等待就绪        pHandle->pDelayMS(1000);                    //失败延时1秒后重试        retry --;    }while(retry);    if(retry == 0)    {        uart_printf("\r\nSIM卡未准备就绪!\r\n");        pHandle->pClearRxData();                    //清除接收计数器        return FALSE;    }    //    //上电删除所有短信//    retry = SIMCOM_DEFAULT_RETRY;                        //重试次数//    do//    {//        if(SIM900_DelMultiSMS(DelSMS) == TRUE)//删除短信//        {//            //uart_printf("上电删除短信成功!\r\n");//            break;//        }//        SIM900_Ready();    //等待就绪//        retry --;//    }while(retry);//    if(retry == 0)//    {//        uart_printf("上电删除短信失败!\r\n");//        SIM900_ClearRxCnt();                //清除计数器//        return FALSE;//    }        //2016-09-20:设置等待消息上报超时时间为1分钟,因为西宁项目卡出现超时情况    switch(pHandle->SimcomModeType)    //不同的芯片存在不一样的初始化    {        case SIMCOM_SIM800:            //SIM800需要等待就绪时间长一些        {            retry = 65;        }break;        default:retry=35;break;    }        //关闭新消息自动上报    while(retry)    {        if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CNMI=0", SIMCOM_DEFAULT_RETRY, 110, "\r\n关闭新消息自动上报失败!\r\n") == FALSE)        {            //return FALSE;        }        else break;        pHandle->pDelayMS(1000);                //延时1秒        retry --;    }    if(retry == 0) return FALSE;         switch(pHandle->SimcomModeType)    //不同的芯片存在不一样的初始化    {        case LYNQ_L700: break;        case SIMCOM_SIM7600:        {            //设置TCP收发相关            retry = SIMCOM_DEFAULT_RETRY;        //重试次数            while(retry)            {                //设置重试次数为3次,并且发送延时为120ms                if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPCCFG=3,100,,1,0,,1000", SIMCOM_DEFAULT_RETRY, 110, "\r\n配置TCP/IP失败!\r\n") == FALSE)                {                    //return FALSE;                }                else break;                pHandle->pDelayMS(1000);                //延时1秒                retry --;            }            if(retry == 0)            {                uart_printf("\r\n设置TCP重发次数以及发送延时失败!\r\n");                pHandle->pClearRxData();                //清除接收计数器                return FALSE;            }            //设置不用等到发送响应            retry = SIMCOM_DEFAULT_RETRY;            //重试次数            while(retry)            {                //设置重试次数为3次,并且发送延时为120ms                if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPSENDMODE=0", SIMCOM_DEFAULT_RETRY, 110, "\r\n不用等待发送ACK设置失败!\r\n") == FALSE)                {                    //return FALSE;                }                else break;                pHandle->pDelayMS(1000);                //延时1秒                retry --;            }            if(retry == 0)            {                uart_printf("\r\n设置不用等待发送ACK失败!\r\n");                pHandle->pClearRxData();                //清除接收计数器            }                        //显示接收数据长度            retry = SIMCOM_DEFAULT_RETRY;            //重试次数            while(retry)            {                //设置重试次数为3次,并且发送延时为120ms                if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPHEAD=1", SIMCOM_DEFAULT_RETRY, 110, "\r\n显示接收数据长度设置失败!\r\n") == FALSE)                {                    //return FALSE;                }                else break;                pHandle->pDelayMS(1000);                //延时1秒                retry --;            }            if(retry == 0)            {                uart_printf("\r\n设置显示接收数据长度失败!\r\n");                pHandle->pClearRxData();                //清除接收计数器                return FALSE;            }                        //不显示接收数据IP头            retry = SIMCOM_DEFAULT_RETRY;        //重试次数            while(retry)            {                //设置重试次数为3次,并且发送延时为120ms                if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPSRIP=0", SIMCOM_DEFAULT_RETRY, 110, "\r\n不显示接收数据IP头设置失败!\r\n") == FALSE)                {                    //return FALSE;                }                else break;                pHandle->pDelayMS(1000);                //延时1秒                retry --;            }            if(retry == 0)            {                uart_printf("\r\n不显示接收数据IP头失败!\r\n");                pHandle->pClearRxData();                //清除接收计数器                return FALSE;            }                    }break;        default:    //2G模块均需要进行设置的            {            //设置GPRS发送数据缓冲区大小            retry = SIMCOM_DEFAULT_RETRY;            //重试次数            do            {                if(SIM900_SetGPRS_PackDatatSize(pHandle) == TRUE)                {                    break;                }                retry --;            }while(retry);            if(retry == 0)            {                uart_printf("\r\n设置GPRS传输大小失败!\r\n");                pHandle->pClearRxData();                //清除接收计数器                return FALSE;            }        }break;    }         pHandle->s_isInitStatus = TRUE;                    //模块成功初始化    pHandle->pClearRxData();                        //清除接收计数器        return TRUE;}  /************************************************************************************************************************** 函数                :    bool SIMCOM_GetModuleInfo(SIMCOM_HANDLE *pHandle, SIMCOM_INFO *pInfo)* 功能                :    获取模块的相关信息* 参数                :    pHandle:句柄;pInfo:信息结构体指针* 返回                :    FALSE:失败;TRUE:成功* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2014-07-29* 最后修改时间         :     2014-10-08* 说明                :     SIMCOM_INFO_SIZE:限制最大长度                        SIMCOM_VER_SIZE:软件版本长度限制                        2014-10-08:在个别模块上面遇到发送AT+GMI后返回了AT+GMI,导致获取失败,如果发现返回了AT+则重新获取,可以避免此问题                        2016-12-07:修改获取模块型号指令为AT+CGMM,用于兼容SIM7600*************************************************************************************************************************/bool SIMCOM_GetModuleInfo(SIMCOM_HANDLE *pHandle, SIMCOM_INFO *pInfo){    u32 i,cnt;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    char *p;    u8 *pData;        //清空缓冲区    pInfo->Manu[0] = 0;    pInfo->Model[0] = 0;    pInfo->Ver[0] = 0;    pInfo->IMEI[0] = 0;        retry = SIMCOM_DEFAULT_RETRY;        //重试次数    //获取制造商信息    do    {        SIMCOM_TestAT(pHandle, 10);        SIMCOM_SendAT(pHandle, "AT+GMI");                                                //请求制造商身份                if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 200))        //等待响应,超时200MS        {            //uart_printf("%s\r\n",pData);            if(strstr((const char*)pData, "AT+") == NULL)                                 //搜索关键字            {                for(i = 0;i < (SIMCOM_INFO_SIZE-1);i ++)                {                    if((pData[2+i] == '\r') || (pData[2+i] == '\n') || (pData[2+i] == '\0')) break;                    pInfo->Manu = pData[2+i];                }                pInfo->Manu = 0;                break;            }        }            SIMCOM_Ready(pHandle);                                                            //等待就绪        pHandle->pDelayMS(1000);                                                        //失败延时1秒后重试        retry --;    }while(retry);    if(retry == 0) return FALSE;        retry = SIMCOM_DEFAULT_RETRY;        //重试次数    //获取型号    do    {        SIMCOM_SendAT(pHandle, "AT+CGMM");            pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 200))        //等待响应,超时200MS        {            for(i = 0;i < (SIMCOM_INFO_SIZE-1);i ++)            {                if((pData[2+i] == '\r') || (pData[2+i] == '\n') || (pData[2+i] == '\0')) break;                pInfo->Model = pData[2+i];            }            pInfo->Model = 0;            break;        }        SIMCOM_Ready(pHandle);                                                            //等待就绪        pHandle->pDelayMS(1000);                                                        //失败延时1秒后重试        retry --;    }while(retry);    if(retry == 0) return FALSE;        retry = SIMCOM_DEFAULT_RETRY;        //重试次数    //获取软件版本    do    {        SIMCOM_SendAT(pHandle, "AT+GMR");        pHandle->pClearRxData();                                                        //清除接收计数器            if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 200))        //等待响应,超时200MS        {            p = strstr((char *)pData, "+GMR: ");            if(p != NULL)             {                p+= strlen("+GMR: ");    //SIM7600前面会有 +GMR:  ,跳过即可                for(i = 0;i < (SIMCOM_VER_SIZE-1);i ++)                {                    if((p == '\r') || (p == '\n') || (p == '\0')) break;                    pInfo->Ver = p;                }                pInfo->Ver = 0;            }            else             {                for(i = 0;i < (SIMCOM_VER_SIZE-1);i ++)                {                    if((pData[2+i] == '\r') || (pData[2+i] == '\n') || (pData[2+i] == '\0')) break;                    pInfo->Ver = pData[2+i];                }                pInfo->Ver = 0;            }                        break;        }        SIMCOM_Ready(pHandle);                                                            //等待就绪        pHandle->pDelayMS(1000);                                                        //失败延时1秒后重试        retry --;    }while(retry);    if(retry == 0) return FALSE;        retry = SIMCOM_DEFAULT_RETRY;        //重试次数    //获取序列号    do    {        SIMCOM_SendAT(pHandle, "AT+GSN");            pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 200))        //等待响应,超时200MS        {            for(i = 0;i < (SIMCOM_INFO_SIZE-1);i ++)            {                if((pData[2+i] == '\r') || (pData[2+i] == '\n') || (pData[2+i] == '\0')) break;                pInfo->IMEI = pData[2+i];            }            pInfo->IMEI = 0;            break;        }        SIMCOM_Ready(pHandle);                                                            //等待就绪        pHandle->pDelayMS(1000);                                                        //失败延时1秒后重试        retry --;    }while(retry);            return TRUE;                                    }   /************************************************************************************************************************** 函数                :    bool SIMCOM_COPS(SIMCOM_HANDLE *pHandle, char pCOPS_Buff[SIMCOM_INFO_SIZE])* 功能                :    获取运营商名称* 参数                :    pHandle:句柄;pCOPS_Buff:运营商名称* 返回                :    FALSE:失败;TRUE:成功* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2014-07-29* 最后修改时间         :     2018-03-24* 说明                :     SIMCOM_INFO_SIZE 限制最大长度*************************************************************************************************************************/bool SIMCOM_COPS(SIMCOM_HANDLE *pHandle, char pCOPS_Buff[SIMCOM_INFO_SIZE]){    u32 i,cnt;    u8 retry = 5;                        //重试次数    char *p;    u8 *pData;        //清空缓冲区    pCOPS_Buff[0] = 0;        switch(pHandle->SimcomModeType)        //不同的芯片存在不一样的初始化    {        case SIMCOM_SIM2000:            //SIM2000需要多次读取,等待的时间比较长        {            retry = 28;        }break;        default:break;    }        //获取运营商    do    {        SIMCOM_SendAT(pHandle, "AT+COPS?");                                            //显示模块当前注册的网络运营商        pHandle->pClearRxData();                                                    //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 20, 150))    //等待响应,超时300MS        {            p = strstr((const char*)pData, "\"");            if(p != NULL)            {                p ++;                for(i = 0;i < (SIMCOM_INFO_SIZE-1);i ++)                {                    if((p == '\r') || (p == '\n') || (p == '\0') || (p == '\"')) break;                    pCOPS_Buff = p;                }                pCOPS_Buff = 0;                return TRUE;            }        }                SIMCOM_Ready(pHandle);                                                    //等待就绪        pHandle->pDelayMS(1000);                                            //延时1秒        retry --;    }while(retry);            return FALSE;                                                                //超时//错误    }   /************************************************************************************************************************** 函数                :    SIMCOM_NETMODE_TYPE SIM7XXX_GetNetworkMode(SIMCOM_HANDLE *pHandle)* 功能                :    获取SIM7XXX系列模块网络制式* 参数                :    pHandle:句柄* 返回                :    SIMCOM_NETMODE_TYPE* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2016-12-29* 最后修改时间         :     2018-03-24* 说明                :     用于从SIM7600模块网络制式                        必须在网络注册成功后进行获取,正常返回                        +CNSMOD: 0,15                        用于SIM7000系列获取网制式*************************************************************************************************************************/SIMCOM_NETMODE_TYPE SIM7XXX_GetNetworkMode(SIMCOM_HANDLE *pHandle){    u32 cnt;    u8 retry = 3;    char *p;    int temp;    u8 *pData;        //获取型号    do    {        SIMCOM_SendAT(pHandle, "AT+CNSMOD?");            pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 200))        //等待响应,超时200MS        {            p = strstr((char *)pData, "+CNSMOD: 0,");            if(p==NULL) p = strstr((char *)pData, "+CNSMOD: 1,");            p += strlen("+CNSMOD: 0,");            temp = atoi(p);            if(temp > 16) continue;             else return (SIMCOM_NETMODE_TYPE)temp;        }                 SIMCOM_Ready(pHandle);                                                    //等待就绪        pHandle->pDelayMS(1000);                                                //失败延时1秒后重试        retry --;    }while(retry);        return SIMCOM_NETMODE_NULL;}    /************************************************************************************************************************** 函数                :    bool SIMCOM_HardwarePowerUP(SIMCOM_HANDLE *pHandle, bool isTest)* 功能                :    SIMCOM模块硬件开机* 参数                :    pHandle:句柄;isTest:是否检测开机是否成功,通过STATUS脚变为高电平可以检测是否开机成功* 返回                :    开机是否成功* 依赖                :    无* 作者                :    cp1300@139.com* 时间                :    2013-10-29* 最后修改时间         :     2018-03-24* 说明                :     用于SIM900模块开机,拉低PWR                        2016-12-07:修改动态监测是否上电成功,增加SIM7600CE兼容*************************************************************************************************************************/bool SIMCOM_HardwarePowerUP(SIMCOM_HANDLE *pHandle, bool isTest){        u8 i,j;        pHandle->pSetDTR_Pin(SIMCOM_L_LEVEL);    //DTR=0,退出低功耗模式    pHandle->s_isInitStatus = FALSE;        //模块没有初始化,需要重新初始化    if(isTest)                                //需要检测是否开机成功    {        if(pHandle->pGetSTATUS_Pin() == SIMCOM_H_LEVEL)                //开机脚已经是高电平了        {            return TRUE;        }                    for(i = 0;i < 2;i ++)        {            pHandle->pSetPWRKEY_Pin(SIMCOM_L_LEVEL);    //拉低1200ms开机            pHandle->pDelayMS(1200);            pHandle->pSetPWRKEY_Pin(SIMCOM_H_LEVEL);    //恢复高电平            for(j = 0;j < 6;j ++)            {                pHandle->pDelayMS(1000);                if(pHandle->pGetSTATUS_Pin() == SIMCOM_H_LEVEL)                //开机脚已经是高电平了                {                    return TRUE;                }            }        }                return FALSE;    }    else    //无需检测是否开机成功    {        pHandle->pSetPWRKEY_Pin(SIMCOM_L_LEVEL);    //拉低1200ms开机        pHandle->pDelayMS(1200);        pHandle->pSetPWRKEY_Pin(SIMCOM_H_LEVEL);    //恢复高电平        pHandle->pDelayMS(3000);;                    //延时3S等待开机完毕                    return TRUE;    }}   /************************************************************************************************************************** 函数                :    bool SIMCOM_HardwarePowerDOWN(SIMCOM_HANDLE *pHandle, bool isTest)* 功能                :    SIMCOM模块硬件关机* 参数                :    pHandle:句柄;isTest:是否检测开机是否成功,通过STATUS脚变为高电平可以检测是否关机成功* 返回                :    关机是否成功* 依赖                :    无* 作者                :    cp1300@139.com* 时间                :    2013-10-29* 最后修改时间         :     2018-03-24* 说明                :     用于SIM900模块关机机,拉低PWR大于1S小于5S                        2016-12-07:优化关机,兼容SIM7600                        一定要先获取模块型号,不同模块关机时间不一样*************************************************************************************************************************/bool SIMCOM_HardwarePowerDOWN(SIMCOM_HANDLE *pHandle, bool isTest){    u8 i,j;        pHandle->s_isInitStatus = FALSE;        //模块没有初始化,需要重新初始化    if(isTest)                                //需要检测是否开机成功    {        if(pHandle->pGetSTATUS_Pin() == SIMCOM_L_LEVEL)                //开机脚已经是低电平了        {            return TRUE;        }        for(i = 0;i < 2;i ++)        {            pHandle->pSetPWRKEY_Pin(SIMCOM_L_LEVEL);                //拉低1200ms关机            switch(pHandle->SimcomModeType)            {                case SIMCOM_SIM7600:                {                    pHandle->pDelayMS(3000);                        //SIM7600关机至少2.5S                }break;                default:                {                    pHandle->pDelayMS(1000);                }break;            }                            pHandle->pDelayMS(200);            pHandle->pSetPWRKEY_Pin(SIMCOM_H_LEVEL);                //恢复高电平            for(j = 0;j < 5;j ++)            {                pHandle->pDelayMS(3000);                            //延时3S等待关机完毕                    if(pHandle->pGetSTATUS_Pin() == SIMCOM_L_LEVEL)        //开机脚已经是低电平了                {                    return TRUE;                }            }        }                return FALSE;    }    else    //无需检测是否开机成功    {        pHandle->pSetPWRKEY_Pin(SIMCOM_L_LEVEL);    //拉低1200ms关机        pHandle->pDelayMS(1200);        pHandle->pSetPWRKEY_Pin(SIMCOM_H_LEVEL);    //恢复高电平        pHandle->pDelayMS(3000);;                    //延时3S等待关机完毕                    return TRUE;    }}  /************************************************************************************************************************** 函数                :    SIMCOM_MODE_TYPE SIMCOM_GetMode(SIMCOM_HANDLE *pHandle)* 功能                :    获取SIMCOM模块的型号* 参数                :    pHandle:句柄* 返回                :    型号,见SIMCOM_MODE_TYPE* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2015-09-12* 最后修改时间         :     2015-09-12* 说明                :     用于识别型号,对应初始化                        2016-12-07:修改指令为AT+CGMM,兼容SIM7600,(旧指令:AT+GOI)*************************************************************************************************************************/SIMCOM_MODE_TYPE SIMCOM_GetMode(SIMCOM_HANDLE *pHandle){    u32 cnt;    u8 retry = SIMCOM_DEFAULT_RETRY+1;    u8 *pData;        //获取型号    do    {        SIMCOM_SendAT(pHandle, "AT+CGMM");            pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 200))        //等待响应,超时200MS        {            if(strstr((char *)pData, "SIM900") != NULL)  return SIMCOM_SIM900;            else if(strstr((char *)pData, "SIM800") != NULL)  return SIMCOM_SIM800;            else if(strstr((char *)pData, "SIM2000") != NULL)  return SIMCOM_SIM2000;            else if(strstr((char *)pData, "SIM7600") != NULL)  return SIMCOM_SIM7600;            else if(strstr((char *)pData, "SIMCOM_SIM868") != NULL)  return SIMCOM_SIM868;            else if(strstr((char *)pData, "SIMCOM_SIM7000C") != NULL)  return SIMCOM_SIM7000C;            else if(strstr((char *)pData, "LYNQ_L700") != NULL)  return LYNQ_L700;                        else             {                uart_printf("未知通信模块:%s\r\n",pData);                return SIMCOM_INVALID;            }        }                 SIMCOM_Ready(pHandle);                                                    //等待就绪        pHandle->pDelayMS(1000);                                                //失败延时1秒后重试        retry --;    }while(retry);        return SIMCOM_INVALID;}  /************************************************************************************************************************** 函数            :    bool SIMCOM_GetServeNumber(PHONE_NUMBER *pServeNumber)* 功能            :    获取短信服务中心号码(会去掉前面的86,限制长度15位,不能用于SIM7000,SIM2000以及电信卡)* 参数            :    pServeNumber:电话号码存储缓冲区指针* 返回            :    FALSE:通信失败;TRUE:通信成功* 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2013-10-20* 最后修改时间     :     2013-10-20* 说明            :     获取SIM卡内部的短信服务中心号码,一般在办理SIM卡的时候已经进行了设置.                    如果没有预置短信中心号码需要使用手机进行设置                    2014-07-12:只要返回OK则认为成功,因为有可能没有设置短信中心号码                    2016-01-26:自动选择是否跳过+86*************************************************************************************************************************/bool SIMCOM_GetServeNumber(SIMCOM_HANDLE *pHandle,  char pPhoneNumber[16]){    u8 i,n;    u32 cnt;    char *p,*p1;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;        do    {            //+CSCA: "+8613800270500",145        SIMCOM_SendAT(pHandle, "AT+CSCA?");                                                //发送"AT+CSCA",获取短信服务中心号码        pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 30, 600))        //等待响应,超时600MS        {            p = strstr((const char*)pData, "+CSCA:");                                    //搜索字符"+CSCA:"            if(p != NULL)                                                                 //搜索成功            {                p = strstr(p+1, "+");    //搜索"+"                if(p != NULL)                {                    p1 = strstr(p+1, "\"");    //搜索"\""                    if(p1 != NULL)                                {                        if(p[0] == '+')            //如果是+开头,则跳过加号                        {                            p+=3;                //跳过+86                        }                                                else if(p[0]=='8' && p[1] == '6') //跳过86                        {                            p+=2;                        }                        n = p1 - p;            //计算电话号码长度                        if(n > 15) n = 15;    //限制号码长度为15字节                        for(i = 0;i < n;i ++)                        {                            pPhoneNumber = p;    //复制电话号码                        }                        pPhoneNumber = '\0';        //添加结束符                         SIMCOM_GSM_debug("短信中心号码:%s\r\n",pPhoneNumber);                                                return TRUE;                    }                }            }            else            {                pPhoneNumber[0] = '\0';                SIMCOM_GSM_debug("短信中心号码:为空,没有设置\r\n");                                return TRUE;            }        }        SIMCOM_Ready(pHandle);                    //等待就绪        pHandle->pDelayMS(1000);                //失败延时1秒后重试        retry --;    }while(retry);        return FALSE;}  /************************************************************************************************************************** 函数            :    bool SIMCOM_GetPhoneNumber(SIMCOM_HANDLE *pHandle, char pPhoneNumber[16])* 功能            :    获取本机号码(会去掉前面的86,限制长度15位,不能用于SIM7000,SIM2000以及电信卡)* 参数            :    pHandle:句柄;pPhoneNumber:号码缓冲区* 返回            :    FALSE:通信失败;TRUE:通信成功* 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2013-10-20* 最后修改时间     :     2018-03-24* 说明            :     通常会预存本机号码到SIM卡,也可能没有(不能用于SIM7000,SIM2000C,不能用于电信卡)                    2014-07-12:只要返回OK则认为成功,因为有可能没有设置电话号码                    2016-01-26:修改字节超时,否则某些卡会出现超时,没有收到OK                                自动选择是否跳过+86*************************************************************************************************************************/bool SIMCOM_GetPhoneNumber(SIMCOM_HANDLE *pHandle, char pPhoneNumber[16]){    u8 n;    u8 i;    u32 cnt;    char *p,*p1;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;         do    {            //+CNUM: "","15871750634",129,7,4        SIMCOM_SendAT(pHandle, "AT+CNUM");                                                //发送"AT++CNUM",获取号码        pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 30, 600))        //等待响应,超时600MS        {            p = strstr((const char*)pData, "+CNUM:");                                    //搜索字符"+CNUM:"                    if(p != NULL)                                                                 //搜索成功            {                p = strstr(p+1, "\",\"");        //搜索","    //开始                if(p != NULL)                {                    p1 = strstr(p+3, "\",");    //搜索",//结束                    if(p1 != NULL)                                {                        p+=3;    //跳过","                        if(p[0] == '+')            //如果是+开头,则跳过加号                        {                            p+=3;                //跳过+86                        }                                                else if(p[0]=='8' && p[1] == '6') //跳过86                        {                            p+=2;                        }                                                n = p1 - p;            //计算电话号码长度                        if(n > 15) n = 15;    //限制号码长度为15字节                        for(i = 0;i < n;i ++)                        {                            pPhoneNumber = p;    //复制电话号码                        }                        pPhoneNumber = '\0';        //添加结束符                        SIMCOM_GSM_debug("本机号码:%s\r\n",pPhoneNumber);                                                return TRUE;                    }                }            }            else            {                pPhoneNumber[0] = '\0';                                SIMCOM_GSM_debug("本机号码:为空,没有设置\r\n");                return TRUE;            }        }                SIMCOM_Ready(pHandle);                //等待就绪        pHandle->pDelayMS(1000);            //失败延时1秒后重试        retry --;    }while(retry);        return FALSE;}  /************************************************************************************************************************** 函数            :    bool SIMCOM_GetBookNumber(SIMCOM_HANDLE *pHandle, u8 index, char pPhoneNumber[16])* 功能            :    从电话簿获取一个电话号码(不能用于SIM7000)* 参数            :    pHandle:句柄;index:电话号码所有,1-255;CenterPhone:电话号码存储缓冲区指针* 返回            :    FALSE:通信失败;TRUE:通信成功* 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2013-10-20* 最后修改时间     :     2016-06-15* 说明            :     用于从电话簿读取一个电话号码,常用语电信卡SIM2000C模块存储本机号码到第一个索引*************************************************************************************************************************/bool SIMCOM_GetBookNumber(SIMCOM_HANDLE *pHandle, u8 index, char pPhoneNumber[16]){    u8 i,n;    u32 cnt;    char *p,*p1;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;    char buff[32];        if(index < 1) return FALSE;                //索引从1开始    do    {            //+CPBR: 1,"152778787878",129,"hone"        sprintf(buff,"AT+CPBR=%d",index);        SIMCOM_SendAT(pHandle, buff);                                                    //发送"AT+CPBR=1",获取号码        pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 30, 600))        //等待响应,超时600MS        {            p = strstr((const char*)pData, "+CPBR:");                    //搜索字符"+CPBR:"                    if(p != NULL)                                                     //搜索成功            {                p = strstr(p+1, ",\"");    //搜索,"    //开始                if(p != NULL)                {                    p1 = strstr(p+2, "\",");    //搜索",//结束                    if(p1 != NULL)                                {                        p+=2;    //跳过,"                        if(p[0] == '+')    //如果是+开头,则跳过加号                        {                            p+=3;    //跳过+86                        }                        else if(p[0]=='8' && p[1] == '6') //跳过86                        {                            p+=2;                        }                                                n = p1 - p;            //计算电话号码长度                        if(n > 15) n = 15;    //限制号码长度为15字节                        for(i = 0;i < n;i ++)                        {                            pPhoneNumber = p;    //复制电话号码                        }                        pPhoneNumber = '\0';        //添加结束符                                                SIMCOM_GSM_debug("号码:%s\r\n",pPhoneNumber);                        return TRUE;                    }                }            }            else            {                pPhoneNumber[0] = '\0';                SIMCOM_GSM_debug("号码:为空\r\n");                                return TRUE;            }        }        SIMCOM_Ready(pHandle);                    //等待就绪        pHandle->pDelayMS(1000);                //失败延时1秒后重试        retry --;    }while(retry);        return FALSE;}  /************************************************************************************************************************** 函数                :    int SIMCOM_GetSignal(SIMCOM_HANDLE *pHandle)* 功能                :    获取信号强度* 参数                :    pHandle:句柄* 返回                :    <0:获取失败;0-31:信号强度;* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2013-10-21* 最后修改时间         :     2013-10-21* 说明                :     无*************************************************************************************************************************/int SIMCOM_GetSignal(SIMCOM_HANDLE *pHandle){    u8 temp;    u32 cnt;    char *p;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;        do    {            //+CSQ: 27,0        //+CSQ: 5,0        //+CSQ: 16,99        SIMCOM_SendAT(pHandle,"AT+CSQ");                                                //发送"AT++CSQ",获取号码        pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 20, 400))        //等待响应,超时400MS        {            p = strstr((const char*)pData, "+CSQ:");                                    //搜索字符"+CSQ:"            if(p != NULL)                                                                 //搜索成功            {                if(p[7] != ',' && p[8] != ',') p[8] = '\0';                temp = atoi(&p[6]);                                return temp;            }            break;        }        SIMCOM_Ready(pHandle);                    //等待就绪        pHandle->pDelayMS(1000);                //失败延时1秒后重试        retry --;    }while(retry);        return -1;}     /************************************************************************************************************************** 函数            :    bool SIMCOM_GetCIMI(SIMCOM_HANDLE *pHandle, char pCIMI[16])* 功能            :    获取SIM卡CIMI号码(SIM卡唯一id,必须存在)* 参数            :    pHandle:句柄;pCIMI:CIMI缓冲区,长15字节* 返回            :    FALSE:通信失败;TRUE:通信成功* 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2017-11-16* 最后修改时间     :     2018-03-24* 说明            :     用于获取卡唯一CIMI编号,防止某些卡无法读取本机号码,这个与卡号一一对应*************************************************************************************************************************/bool SIMCOM_GetCIMI(SIMCOM_HANDLE *pHandle, char pCIMI[16]){    u32 cnt;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;        do    {            //460041037206894        SIMCOM_SendAT(pHandle, "AT+CIMI");                                                //发送"AT+CIMI"        pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 20, 200))        //等待响应,超时200MS        {            if(pData[0]!='\r' || pData[1]!='\n') continue;            memcpy(pCIMI, &pData[2], 15);    //跳过前面\r\n            pCIMI[15] = 0;        //添加结束符                        SIMCOM_GSM_debug("获取CIMI成功:%s\r\n", pCIMI);            return TRUE;        }                SIMCOM_Ready(pHandle);                                                            //等待就绪        pHandle->pDelayMS(1000);                                                        //失败延时1秒后重试        retry --;    }while(retry);        return FALSE;}     /************************************************************************************************************************** 函数                :    bool SIM7000C_GetNB_APN(SIMCOM_HANDLE *pHandle, char pAPN[17])* 功能                :    获取SIM7000C NBIOT 接入点* 参数                :    pHandle:句柄;pAPN:接入点缓冲区* 返回                :    TRUE:成功;FALSE:失败* 依赖                :    底层* 作者                :    cp1300@139.com* 时间                :    2018-01-16* 最后修改时间         :     2018-01-16* 说明                :     必须是NBIOT模式才能使用*************************************************************************************************************************/bool SIM7000C_GetNB_APN(SIMCOM_HANDLE *pHandle, char pAPN[17]){    u32 cnt;    char *p;    u8 retry = SIMCOM_DEFAULT_RETRY;        //重试次数    u8 *pData;    u8 i;     do    {            //+CGNAPN: 1,"ctnb"        SIMCOM_SendAT(pHandle, "AT+CGNAPN");                                            //发送AT指令        pHandle->pClearRxData();                                                        //清除接收计数器        if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 2000))        //等待响应,超时2000MS        {            p = strstr((const char*)pData, "+CGNAPN: 1,\"");                            //搜索字符+CGNAPN: 1,"            if(p != NULL)                                                                 //搜索成功            {                p += strlen("+CGNAPN: 1,\"");                for(i = 0;i < 17;i ++)                {                    if(p == '\"')                                            //结束符号位 ”                    {                        pAPN = 0;                        if(i == 0) break;                                        //太短了                        return TRUE;                    }                    pAPN = p;                }            }        }                SIMCOM_Ready(pHandle);                                                    //等待就绪        pHandle->pDelayMS(1000);                                                //失败延时1秒后重试        retry --;    }while(retry);        return FALSE;} [url=][/url]

//SIMCOM_GSM.h
[url=][/url]
/************************************************************************************************************* * 文件名:            SIMCOM_GSM.h * 功能:            SIMCOM GSM相关接口 * 作者:            cp1300@139.com * 创建时间:        2015-02-15 * 最后修改时间:    2018-03-23 * 详细:            *************************************************************************************************************/#ifndef _SIMCOM_GSM_H_#define _SIMCOM_GSM_H_#include "system.h"#include "simcom.h" bool SIMCOM_NetworkConfig(SIMCOM_HANDLE *pHandle, SIMCOM_MODE_TYPE ModeType, NETWORK_CONFIG_TYPE *pConfig);        //SIMCOM网络配置SIM_CARD_STATUS SIMCOM_GetCPIN(SIMCOM_HANDLE *pHandle);                                                            //获取SIM卡状态SIMCOM_NETSTATUS SIM900_GetGSMNetworkStatus(SIMCOM_HANDLE *pHandle);                                            //获取GSM网络注册状态SIMCOM_NETSTATUS SIMCOM_GetDataNetworkStatus(SIMCOM_HANDLE *pHandle);                                            //获取数据网络注册状态bool SIMCOM_ModuleInit(SIMCOM_HANDLE *pHandle);                                                                    //初始化SIMCOM模块基本配置(不允许失败)bool SIMCOM_GetModuleInfo(SIMCOM_HANDLE *pHandle, SIMCOM_INFO *pInfo);                                            //获取模块的相关信息bool SIMCOM_COPS(SIMCOM_HANDLE *pHandle, char pCOPS_Buff[SIMCOM_INFO_SIZE]);                                    //获取运营商名称SIMCOM_NETMODE_TYPE SIM7XXX_GetNetworkMode(SIMCOM_HANDLE *pHandle);                                                //获取SIM7XXX系列模块网络制式bool SIMCOM_HardwarePowerUP(SIMCOM_HANDLE *pHandle, bool isTest);                                                //SIMCOM模块硬件开机bool SIMCOM_HardwarePowerDOWN(SIMCOM_HANDLE *pHandle, bool isTest);                                                //SIMCOM模块硬件关机SIMCOM_MODE_TYPE SIMCOM_GetMode(SIMCOM_HANDLE *pHandle);                                                        //获取SIMCOM模块的型号int SIMCOM_GetSignal(SIMCOM_HANDLE *pHandle);                                                                    //获取信号强度bool SIMCOM_GetBookNumber(SIMCOM_HANDLE *pHandle, u8 index, char pPhoneNumber[16]);                                //从电话簿获取一个电话号码(不能用于SIM7000)bool SIMCOM_GetPhoneNumber(SIMCOM_HANDLE *pHandle, char pPhoneNumber[16]);                                        //获取本机号码(会去掉前面的86,限制长度15位,不能用于SIM7000,SIM2000以及电信卡)bool SIMCOM_GetServeNumber(SIMCOM_HANDLE *pHandle,  char pPhoneNumber[16]);                                        //获取短信服务中心号码(会去掉前面的86,限制长度15位,不能用于SIM7000,SIM2000以及电信卡)bool SIMCOM_GetCIMI(SIMCOM_HANDLE *pHandle, char pCIMI[16]);                                                    //获取SIM卡CIMI号码(SIM卡唯一id,必须存在)bool SIM7000C_GetNB_APN(SIMCOM_HANDLE *pHandle, char pAPN[17]);                                                    //获取SIM7000C NBIOT 接入点 #endif /*_SIMCOM_GSM_H_*/[url=][/url]

//SIMCOM_USER.c
[url=][/url]
/************************************************************************************************************* * 文件名:            SIMCOM_USER.c * 功能:            SIMCOM用户层函数 * 作者:            cp1300@139.com * 创建时间:        2015-02-15 * 最后修改时间:    2018-03-23 * 详细:            *************************************************************************************************************/#include "system.h"#include "usart.h"#include "string.h"#include "ucos_ii.h"#include "SIMCOM_USER.h"#include "SIMCOM_GSM.h"#include "SIMCOM_GPRS.h"#include "SIMCOM_AT.h"#include "SIMCOM.h" bool g_SIMC0M_USER_Debug = TRUE;    //应用层指令调试状态 //调试开关#define SIMCOM_USER_DBUG        1#if SIMCOM_USER_DBUG    #include "system.h"    #define SIMCOM_USER_debug(format,...)    {if(g_SIMC0M_USER_Debug){uart_printf(format,##__VA_ARGS__);}}#else    #define SIMCOM_USER_debug(format,...)    /\/#endif    //SIMCOM_USER_DBUG    const char  *const SIMCOM_NETWORK_NAME[18] = {"未注册","GSM","GPRS","EGPRS (EDGE)","WCDMA","HSDPA only(WCDMA)","HSUPA only(WCDMA)","HSPA (HSDPA and HSUPA, WCDMA)","LTE","TDS-CDMA","TDS-HSDPA only","TDS-HSUPA only","TDS- HSPA (HSDPA and HSUPA)","CDMA","EVDO","HYBRID (CDMA and EVDO)","1XLTE(CDMA and LTE)","未知,错误"};   /************************************************************************************************************************** 函数                :    bool SIMCOM_Init(SIMCOM_HANDLE *pHandle,                            bool (* pSendData)(u8 *pDataBuff, u16 DataLen),                                                                        int (* pReadData)(u8 **pDataBuff, u8 ByteTimeOutMs, u16 TimeOutMs, u16 *pReceiveDelay),                                void (*pClearRxData)(void),                                                                                            void (*pSetDTR_Pin)(u8 Level),                                                                                        void (*pSetPWRKEY_Pin)(u8 Level),                                                                                    u8 (*pGetSTATUS_Pin)(void),                                u8 (*pGetDCD_Pin)(void),                            void (*pDelayMS)(u32 ms),                                                                                            void (*pIWDG_Feed)(void)* 功能                :    初始化SIMCOM句柄接口* 参数                :    pSl651_Handle:句柄;                        pSendCallBack:发送回调函数(pDataBuff:发送数据缓冲区,DataLen:发送数据长度)                        pReadCallBack:接收数据回调函数,会等待直到数据被写入到接收缓冲区(pDataBuff:接收数据缓冲区,ByteTimeOut:等待的字节超时时间,单位ms,TimeOut:数据包超时时间,单位ms)                        pClearRxData:清除接收缓冲区函数,用于清除接收数据缓冲区数据                        pSetDTR_PinTR引脚电平控制-用于控制sleep模式或者退出透传模式                        pSetPWRKEY_PinWRKEY开机引脚电平控制-用于开机                        pGetSTATUS_Pin:获取STATUS引脚电平-用于指示模块上电状态                        pGetDCD_Pin:获取DCD引脚电平-高电平AT指令模式,低电平为透传模式                        pDelayMS:系统延时函数                        pIWDG_Feed:清除系统看门狗(可以为空)* 返回                :    无* 依赖                :    TRUE:成功,FALSE:失败* 作者                :    cp1300@139.com* 时间                :    2018-03-24* 最后修改时间         :     2018-03-24* 说明                :     除pIWDG_Feed接口可以为空,其余接口均不能为空,否则程序会崩溃*************************************************************************************************************************/bool SIMCOM_Init(SIMCOM_HANDLE *pHandle,        bool (* pSendData)(u8 *pDataBuff, u16 DataLen),                                            //发送数据接口,如果发送失败,返回FALSE,成功返回TRUE;        int (* pReadData)(u8 **pDataBuff, u8 ByteTimeOutMs, u16 TimeOutMs, u16 *pReceiveDelay),    //接收数据接口,返回数据长度,如果失败返回<=0,成功,返回数据长度        void (*pClearRxData)(void),                                                                //清除接收缓冲区函数,用于清除接收数据缓冲区数据        void (*pSetDTR_Pin)(u8 Level),                                                            //DTR引脚电平控制-用于控制sleep模式或者退出透传模式        void (*pSetPWRKEY_Pin)(u8 Level),                                                        //PWRKEY开机引脚电平控制-用于开机        u8 (*pGetSTATUS_Pin)(void),                                                                //获取STATUS引脚电平-用于指示模块上电状态        u8 (*pGetDCD_Pin)(void),                                                                //获取DCD引脚电平-高电平AT指令模式,低电平为透传模式        void (*pDelayMS)(u32 ms),                                                                //系统延时函数        void (*pIWDG_Feed)(void)                                                                //清除系统看门狗(可以为空)    ){    if(pHandle == NULL)     {        DEBUG("无效的句柄!\r\n");        return FALSE;    }    //所需变量    pHandle->SimcomModeType = SIMCOM_INVALID;                            //模块型号    pHandle->TelecomCarr[0] = 0;                                        //运营商名称    memset(&pHandle->SIMCOM_Info, 0, sizeof(SIMCOM_INFO));                //SIMCOM通信模块相关信息结构体    memset(&pHandle->NetworkConfig, 0, sizeof(NETWORK_CONFIG_TYPE));    //网络模式设置    pHandle->NetworkMode = SIMCOM_NETMODE_NULL;                            //当前网络制式            //底层通信接口    pHandle->pSendData = pSendData;                                        //发送数据接口,如果发送失败,返回FALSE,成功返回TRUE;    pHandle->pReadData = pReadData;                                        //接收数据接口,返回数据长度,如果失败返回<=0,成功,返回数据长度    pHandle->pClearRxData = pClearRxData;                                //清除接收缓冲区函数,用于清除接收数据缓冲区数据    pHandle->pSetDTR_Pin = pSetDTR_Pin;                                    //DTR引脚电平控制-用于控制sleep模式或者退出透传模式    pHandle->pSetPWRKEY_Pin = pSetPWRKEY_Pin;                            //PWRKEY开机引脚电平控制-用于开机    pHandle->pGetSTATUS_Pin = pGetSTATUS_Pin;                            //获取STATUS引脚电平-用于指示模块上电状态    pHandle->pGetDCD_Pin = pGetDCD_Pin;                                    //获取DCD引脚电平-高电平AT指令模式,低电平为透传模式    //系统接口    pHandle->pDelayMS = pDelayMS;                                        //系统延时函数    pHandle->pIWDG_Feed = pIWDG_Feed;                                    //清除系统看门狗(可以为空)    //内部状态定义    pHandle->s_isInitStatus = FALSE;                                    //用于记录模块初始化状态,复位或上电后变为无效    //检查是否有接口为空    if(pHandle->pSendData==NULL || pHandle->pReadData==NULL || pHandle->pClearRxData==NULL || pHandle->pSetDTR_Pin==NULL || pHandle->pSetPWRKEY_Pin==NULL ||         pHandle->pGetSTATUS_Pin==NULL || pHandle->pGetDCD_Pin==NULL || pHandle->pDelayMS==NULL)    {        DEBUG("错误,有回调接口为空!\r\n");        return FALSE;    }        return TRUE;}   /************************************************************************************************************************** 函数            :    void SIMCOM_PrintfModel(SIMCOM_HANDLE *pHandle, SIMCOM_MODE_TYPE ModeType, const char **pModeInof)* 功能            :    显示并打印模块型号* 参数            :    pHandle:句柄;ModeType:模块型号;pModeInof:返回模块型号信息(不需要可以为空)* 返回            :    无* 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2017-10-17* 最后修改时间    :     2018-03-24* 说明            :     *************************************************************************************************************************/ void SIMCOM_PrintfModel(SIMCOM_HANDLE *pHandle, SIMCOM_MODE_TYPE ModeType, const char **pModeInof){    switch(ModeType)    {        case SIMCOM_SIM900 :    //默认为SIM900        {            if(pModeInof!=NULL) *pModeInof = "SIM900系列";//通信模块型号                uart_printf("[DTU]通信模块为SIM900\r\n");            }break;        case SIMCOM_SIM800 :    //SIM800        {            if(pModeInof!=NULL) *pModeInof = "SIM800系列";            //通信模块型号            uart_printf("[DTU]通信模块为SIM800\r\n");        }break;        case SIMCOM_SIM2000    :    //SIM2000        {                        if(pModeInof!=NULL) *pModeInof = "SIM2000系列";            //通信模块型号            uart_printf("[DTU]通信模块为SIM2000\r\n");        }break;        case SIMCOM_SIM7600    :    //SIM7600        {            if(pModeInof!=NULL) *pModeInof = "SIM7600系列";            //通信模块型号            uart_printf("[DTU]通信模块为SIM7600\r\n");        }break;        case SIMCOM_SIM868:        //SIM868        {            if(pModeInof!=NULL) *pModeInof = "SIM868系列";            //通信模块型号            uart_printf("[DTU]通信模块为SIM868模块\r\n");        }break;        case SIMCOM_SIM7000C:    //SIM7000C        {            if(pModeInof!=NULL) *pModeInof = "SIM7000C系列";        //通信模块型号            uart_printf("[DTU]通信模块为SIM7000C\r\n");        }break;        case LYNQ_L700:        //LYNQ_L700        {            if(pModeInof!=NULL) *pModeInof = "L700系列";            //通信模块型号            uart_printf("[DTU]通信模块为L700模块\r\n");        }break;        case SIMCOM_INVALID    :    //无效则默认        {            if(pModeInof!=NULL) *pModeInof = "未知";                //通信模块型号            uart_printf("[DTU]通信模块未知!\r\n");        }break;    }}     /************************************************************************************************************************** 函数            :    SIMCOM_USER_ERROR SIMCOM_RegisNetwork(SIMCOM_HANDLE *pHandle, u16 Retry, u16 NetworkDelay,const char **pModeInof)* 功能            :    SIMCOM模块上电初始化并注册网络* 参数            :    pHandle:句柄;Retry:初始化重试次数>0;NetworkDelay:注册网络延时时间,单位S;pModeInof:返回模块型号信息(不需要可以为空)* 返回            :    SIMCOM_USER_ERROR    * 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2014-08-18* 最后修改时间    :     2018-03-24* 说明            :     用于通信模块上电并初始化操作        *************************************************************************************************************************/ SIMCOM_USER_ERROR SIMCOM_RegisNetwork(SIMCOM_HANDLE *pHandle, u16 Retry, u16 NetworkDelay,const char **pModeInof){    SIMCOM_NETSTATUS NetStatus;    SIMCOM_MODE_TYPE ModeType = SIMCOM_INVALID;                    //初始化模块型号无效    SIMCOM_NETMODE_TYPE NetworkMode = SIMCOM_NETMODE_NULL;        //初始化为未知模式    SIMCOM_USER_ERROR Error = SIMCOM_NULL_ERROR;                //初始化状态        u16 pcnt,cnt;    u8 NotCnt,SeaCnt,TurCnt,UnkCnt,ErrCnt;    bool isCart = FALSE;    u8 SIM_NotReadyCnt = 0;                                        //SIM卡未准备就绪计数器        Retry += 1;                                                    //重试次数至少1次    //模块上电    for(pcnt = 0;pcnt < Retry;pcnt ++)                            //上电循环    {        SIM_NotReadyCnt = 0;                                    //SIM卡未准备就绪计数器复位        if(pHandle->pIWDG_Feed!=NULL) pHandle->pIWDG_Feed();    //喂狗         if(pHandle->pGetSTATUS_Pin()==SIMCOM_L_LEVEL)            //模块没有上电            {            pHandle->s_isInitStatus = FALSE;                    //模块没有初始化            SIMCOM_USER_debug("[SIMCOM]:模块没有上电!\r\n");            if(SIMCOM_HardwarePowerUP(pHandle, TRUE) == TRUE)    //上电            {                SIMCOM_USER_debug("[SIMCOM]:开机成功!\r\n");                if(SIMCOM_TestAT(pHandle, 50) != TRUE)                    //发送AT测试命令                {                    if(pModeInof!=NULL) *pModeInof = "模块未知";                    SIMCOM_USER_debug("[SIMCOM]:通信错误,串口错误!\r\n");                }            }            else            {                if(pModeInof!=NULL) *pModeInof = "模块未知";                SIMCOM_USER_debug("[SIMCOM]:开机失败!\r\n");                Error = SIMCOM_POWER_UP_ERROR;                    //开机失败            }                    }                //上电完毕后初始化模块        if(pHandle->pGetSTATUS_Pin() == SIMCOM_H_LEVEL)                {            //模块初始化网络            if(NetworkDelay == 0) NetworkDelay = 0xffff;                //为0,一直等待                NotCnt=SeaCnt=TurCnt=UnkCnt=ErrCnt=0;                        //初始化注册状态计数器为0             //获取模块型号            if(ModeType == SIMCOM_INVALID)            {                SIMCOM_SetParametersReturnBool(pHandle, "ATE 0", SIMCOM_DEFAULT_RETRY, 110, "\r\n关闭AT回显模式失败!\r\n");                pHandle->pDelayMS(500);                ModeType = SIMCOM_GetMode(pHandle);                        //获取模块型号                SIMCOM_PrintfModel(pHandle, ModeType, pModeInof);        //打印显示通信模块型号                    }            //型号获取成功了,更新信息            if(ModeType!=SIMCOM_INVALID)            {                pHandle->SimcomModeType = ModeType;                        //上电初始化设置通信模块型号                }                        //根据模块类型进行初始化,如果是SIM7000C,需要选择工作在GSM模式还是NBIOT模式            if(SIMCOM_NetworkConfig(pHandle, ModeType, &pHandle->NetworkConfig)==FALSE)            {                uart_printf("[DTU]初始化通信模块网络模式失败了!\r\n");                }                        //初始化获取网络信息            for(cnt = 0;cnt < NetworkDelay;cnt ++)            {                if(pHandle->pGetSTATUS_Pin()==SIMCOM_L_LEVEL)                 {                    Error = SIMCOM_POWER_UP_ERROR;            //异常断电                    uart_printf("[DTU]异常断电了,请检查供电是否稳定!\r\n");                        break;                                    //模块没有上电,初始化                }                                if(ModeType == SIMCOM_INVALID)                {                    SIMCOM_SetParametersReturnBool(pHandle, "ATE 0", SIMCOM_DEFAULT_RETRY, 110, "\r\n关闭AT回显模式失败!\r\n");                    pHandle->pDelayMS(500);                    ModeType = SIMCOM_GetMode(pHandle);                                //获取模块型号                    pHandle->SimcomModeType = ModeType;                                //上电初始化设置通信模块型号                        SIMCOM_PrintfModel(pHandle, ModeType, pModeInof);                //打印显示通信模块型号                }                                if(isCart == FALSE)                                                    //卡未检测到,则一直重新检测                {                    if(SIMCOM_GetCPIN(pHandle)==SIM_READY)                    {                        isCart = TRUE;    //卡检测成功                        uart_printf("\r\nSIM卡准备就绪!\r\n");                    }                    else                    {                        uart_printf("\r\nSIM卡未准备就绪!\r\n");                        Error = SIMCOM_SIM_NOT_REALYE;                                //卡未就绪                    }                }                                                //2018-01-18 增加SIM7000C NB模式网络注册状态获取支持                if((ModeType == SIMCOM_SIM7000C) && (pHandle->NetworkConfig.NB_EnableMode==1)) //如果是SIM7000C,并且开启了NB模式                {                    NetStatus = SIMCOM_GetDataNetworkStatus(pHandle);                //获取数据网络网络注册状态                }                else                {                    NetStatus = SIM900_GetGSMNetworkStatus(pHandle);                //获取GSM网络注册状态                }                 SIMCOM_USER_debug("[DTU]网络注册状态%d!\r\n",NetStatus);                //一直出现网络未注册以及注册拒绝,重启,有些卡会先出现拒绝,然后出现注册成功                switch(NetStatus)                {                    case SIMCOM_NET_NOT    :                        {                        NotCnt++;                        //2017-09-09 增加如果连续15次未检测到卡,并且未注册,则直接退出,返回未插卡                        if(SIMCOM_GetCPIN(pHandle)==SIM_NOT_READY)                        {                            Error = SIMCOM_SIM_NOT_REALYE;    //卡未就绪                            SIM_NotReadyCnt ++;                //SIM卡未准备就绪计数器增加                        }                        else                        {                            SIM_NotReadyCnt = 0;            //SIM卡未就绪计数器复位                        }                    }break;    //未注册                    case SIMCOM_NET_ROA    :                    //已经注册,但是漫游                    case SIMCOM_NET_YES    :                    //已经注册                    {                        SIM_NotReadyCnt = 0;                //SIM卡未就绪计数器复位                        if(pHandle->s_isInitStatus == FALSE)//模块没有初始化                        {                            if(SIMCOM_ModuleInit(pHandle) == FALSE)                        //上电后初始化模块基本配置                            {                                SIMCOM_USER_debug("[DTU]初始化失败!\r\n");                                    if(isCart==TRUE) Error = SIMCOM_INIT_ERROR;                //卡初始化成功了,才返回初始化错误                                goto reset;                            }                        }                                                //获取模块信息                        if( SIMCOM_GetModuleInfo(pHandle, &pHandle->SIMCOM_Info) == TRUE)        //获取模块的相关信息                        {                            SIMCOM_USER_debug("\r\n制造商:%s\r\n",pHandle->SIMCOM_Info.Manu);                                SIMCOM_USER_debug("模块型号:%s\r\n",pHandle->SIMCOM_Info.Model);                            SIMCOM_USER_debug("软件版本:%s\r\n",pHandle->SIMCOM_Info.Ver);                            SIMCOM_USER_debug("模块序列号:%s\r\n",pHandle->SIMCOM_Info.IMEI);                        }                        else                        {                            SIMCOM_USER_debug("\r\n获取模块信息失败!\r\n");                        }                        //获取运营商信息                        if(SIMCOM_COPS(pHandle, pHandle->TelecomCarr) == TRUE)        //获取运营商名称                        {                            SIMCOM_USER_debug("运营商信息:%s\r\n", pHandle->TelecomCarr);                            }                        else                        {                            SIMCOM_USER_debug("获取运营商信息失败!\r\n");                        }                                                //如果是SIM7600 SIM7000C模块,则需要获取网络制式                        switch(ModeType)                        {                            case SIMCOM_SIM7600:                            case SIMCOM_SIM7000C:                            {                                NetworkMode = SIM7XXX_GetNetworkMode(pHandle);            //获取SIM7XXX系列模块网络制式                                pHandle->NetworkMode = NetworkMode;                        //记录全局网络制式,必须在获取短信中心号码之前进行获取,因为电信卡无短信中心号码用于初始化                                if(NetworkMode > 16)                                {                                    SIMCOM_USER_debug("网络制式:获取失败\r\n");                                }                                else                                {                                    SIMCOM_USER_debug("网络制式:%s\r\n",SIMCOM_NETWORK_NAME[NetworkMode]);                                }                            }break;                            default: //2G                            {                                pHandle->NetworkMode = SIMCOM_NETMODE_GSM;                //其它2G模块默认GSM网络                            }break;                        }                                                Error = SIMCOM_INIT_OK;                            //初始化成功                        return Error;                                    //已经注册并初始化了                    }                    case SIMCOM_NET_SEA    :    SeaCnt++;break;    //未注册,正在搜索                    case SIMCOM_NET_TUR    :    TurCnt++;break;    //注册被拒绝                    case SIMCOM_NET_UNK    :    UnkCnt++;break;    //未知                    default                :    ErrCnt++;break;    //错误                }                                if((TurCnt > 60) || (UnkCnt > 20) || (ErrCnt > 20))         //注册被拒绝,或者错误                {                    if(isCart==TRUE) Error = SIMCOM_REG_ERROR;                //卡初始化成功了,才返回初注册失败                    SIMCOM_USER_debug("[DTU]模块重启!\r\n");                    if(SIMCOM_HardwarePowerDOWN(pHandle, TRUE) == FALSE)                    {                        SIMCOM_USER_debug("[DTU]:关机失败!\r\n");                    }                    break;                }                                //SIM卡未就绪次数过多                if(SIM_NotReadyCnt > 16)                {                                        uart_printf("[DTU]:多次检测到卡未就绪!模块重启!\r\n");                    if(SIMCOM_HardwarePowerDOWN(pHandle, TRUE) == FALSE)                    {                        SIMCOM_USER_debug("[DTU]:关机失败!\r\n");                    }                    break;                }                                            //延时                pHandle->pDelayMS(800);                if(pHandle->pIWDG_Feed!=NULL) pHandle->pIWDG_Feed();    //喂狗                            }                //网络注册失败或模块初始化失败            reset:                        if(SIMCOM_HardwarePowerDOWN(pHandle, TRUE) == TRUE)                //关闭电源            {                uart_printf("[DTU]:网络初始化失败,模块关机成功!\r\n");            }            else            {                uart_printf("[DTU]:网络初始化失败,模块关机失败!\r\n");            }        }        else        {            Error = SIMCOM_POWER_UP_ERROR;                            //开机失败        }    }        //显示错误信息    switch(Error)    {        case SIMCOM_INIT_OK                :    //初始化成功            {            uart_printf("[DTU]:模块上电或初始成功!\r\n");        }break;        case SIMCOM_POWER_UP_ERROR        :    //上电错误        {            uart_printf("[DTU]:模块上电错误!\r\n");        }break;        case SIMCOM_REG_ERROR            :    //注册出错(超时)        {            uart_printf("[DTU]:模块注册网络出错(超时)!\r\n");        }break;        case SIMCOM_INIT_ERROR            :    //初始化配置错误        {            uart_printf("[DTU]:模块初始化配置出错!\r\n");        }break;        case SIMCOM_SIM_NOT_REALYE        :    //SIM卡未就绪导致上电失败        {            uart_printf("[DTU]:模块SIM卡未就绪!\r\n");        }break;        default:         {            uart_printf("[DTU]:未知的错误!\r\n");        }break;    }            return Error;    }     /************************************************************************************************************************** 函数            :    bool SIMCOM_PhoneMessageNumberInitialize(SIMCOM_HANDLE *pHandle, u8 retry)* 功能            :    SIMCOM 初始化获取短信中心号码以及本机号码,信号强度,CIMI(结果存放在句柄pHandle中)* 参数            :    pHandle:句柄;Retry:初始化重试次数>0* 返回            :    TRUE成功,FALSE:失败    * 依赖            :    底层* 作者            :    cp1300@139.com* 时间            :    2014-08-18* 最后修改时间    :     2018-03-24* 说明            :     用于网络初始化之后进行初始化获取相关信息,需要提前初始化网络模块型号以及网络制式                    短信中心号码存放在:pHandle->ServiceCenterPhoneNumber;                        电话号码存放在:pHandle->LocalPhoneNumber;                        信号强度存放在:pHandle->Singal;                    SIM卡CIMI号码存放在pHandle->SIM_CIMI;                    2016-06-15:SIM2000C使用电信SIM卡时,过快读取本机号码会失败,增加延时,确保读取成功                    2016-11-16:增加获取短信中心号码延时                    2017-12-05:NBIO 模块不读取电话号码*************************************************************************************************************************/ bool SIMCOM_PhoneMessageNumberInitialize(SIMCOM_HANDLE *pHandle, u8 retry){    u8 i;                //重试计数器    int Singal;    bool status;    bool isReadServerNumber = TRUE;    //是否需要获取短信中心号码,电信卡无需获取     //测试AT指令    SIMCOM_Ready(pHandle);    if(SIMCOM_TestAT(pHandle, 20) != TRUE)    {                return FALSE;    }            retry += 1;    //获取短信中心号码    if(pHandle->SimcomModeType == SIMCOM_SIM2000)            //电信模块无需获取短信中心号码    {        isReadServerNumber = FALSE;    }    else if(pHandle->SimcomModeType == LYNQ_L700)            //L700 NBIOT 无需获取短信中心号码    {        isReadServerNumber = FALSE;    }    else if(pHandle->SimcomModeType==SIMCOM_SIM7000C)        //SIM7000C    {        isReadServerNumber = FALSE; //sim7000不支持    }    else if(pHandle->SimcomModeType==SIMCOM_SIM7600)        //SIM7600    {        switch(pHandle->NetworkMode)                        //查看网络制式,如果是CDMA(电信卡)则不需要获取短信中心号码        {            case SIMCOM_NETMODE_CDMA    ://CDMA            case SIMCOM_NETMODE_EVDO    ://EVDO            case SIMCOM_NETMODE_HYBRID    ://HYBRID (CDMA and EVDO)            case SIMCOM_NETMODE_1XLTE    ://1XLTE(CDMA and LTE)            {                isReadServerNumber = FALSE;            }break;        }    }     if(isReadServerNumber)                //需要获取短信中心号码    {        for(i = 0;i < retry;i ++)        {            if(SIMCOM_GetServeNumber(pHandle, pHandle->ServiceCenterPhoneNumber) == TRUE)                //获取短信服务中心号码成功            {                if(pHandle->ServiceCenterPhoneNumber[0] == 0)                {                    SIMCOM_USER_debug("短信中心号码为空\r\n");                }                else                {                    SIMCOM_USER_debug("短信中心号码:%s\r\n",pHandle->ServiceCenterPhoneNumber);                }                break;            }            else            {                SIMCOM_WaitSleep(pHandle, 100);                SIMCOM_Ready(pHandle);                pHandle->pDelayMS(1000);            }        }        if(i==retry) return FALSE;    }    else    {        pHandle->pDelayMS(2000);    //等待2s钟        strcpy(pHandle->ServiceCenterPhoneNumber, "13800818500");    //短信中心号码-固定值,防止为空        SIMCOM_USER_debug("[缺省]短信中心号码:%s\r\n",pHandle->ServiceCenterPhoneNumber);    }        //获取信号强度    for(i = 0;i < retry;i ++)    {        Singal = SIMCOM_GetSignal(pHandle);                //获取信号强度        if((Singal > 0) && (Singal!=99))         {            pHandle->Singal = (u8)Singal;            SIMCOM_USER_debug("信号强度 <%02d>!\r\n" ,Singal);            break;        }        else        {            pHandle->Singal = 0;            //没有读取到,延时2秒            pHandle->pDelayMS(2000);        //等待2s钟        }        SIMCOM_WaitSleep(pHandle, 100);        SIMCOM_Ready(pHandle);        pHandle->pDelayMS(1000);            //等待1s钟    }        //获取本机号码    for(i = 0;i < retry;i ++)    {        if(pHandle->NetworkMode == LYNQ_L700)            //L700 NBIOT 无法获取        {            pHandle->pDelayMS(1000);                    //等待1s钟            pHandle->LocalPhoneNumber[0] = 0;                        return TRUE;        }        else if(pHandle->NetworkMode == SIMCOM_SIM7000C)    //SIM7000C 无法获取        {            pHandle->pDelayMS(1000);            //等待1s钟            pHandle->LocalPhoneNumber[0] = 0;                        return TRUE;        }        else if(pHandle->SimcomModeType==SIMCOM_SIM7600)        //SIM7600,SIM7000C        {            switch(pHandle->NetworkMode)                        //查看网络制式,如果是CDMA(电信卡)则不需要获取短信中心号码            {                case SIMCOM_NETMODE_CDMA    ://CDMA                case SIMCOM_NETMODE_EVDO    ://EVDO                case SIMCOM_NETMODE_HYBRID    ://HYBRID (CDMA and EVDO)                case SIMCOM_NETMODE_1XLTE    ://1XLTE(CDMA and LTE)                {                    status = SIMCOM_GetBookNumber(pHandle, 1, pHandle->LocalPhoneNumber);    //从电话簿中读取一个电话号码                }break;                default: //其他制式可以读取                {                    status = SIMCOM_GetPhoneNumber(pHandle, pHandle->LocalPhoneNumber);    //读取本机号码                }break;             }        }        else if(pHandle->SimcomModeType == SIMCOM_SIM2000) //SIM2000        {            status = SIMCOM_GetBookNumber(pHandle, 1, pHandle->LocalPhoneNumber);    //从电话簿中读取一个电话号码        }                    else    //其它模块        {            status = SIMCOM_GetPhoneNumber(pHandle, pHandle->LocalPhoneNumber);    //读取本机号码        }                        if(status== TRUE)            //获取本机号码成功        {            pHandle->LocalPhoneNumber[15] = 0;            if(pHandle->LocalPhoneNumber[0] == 0)            {                SIMCOM_USER_debug("本机号码为空\r\n");            }            else            {                SIMCOM_USER_debug("本机号码:%s\r\n",pHandle->LocalPhoneNumber);            }            break;        }        else        {            SIMCOM_WaitSleep(pHandle, 100);            SIMCOM_Ready(pHandle);            pHandle->pDelayMS(2000);        //等待2s钟        }    }    if(i==retry) return FALSE;            //获取SIM卡CIMI号码    for(i = 0;i < retry;i ++)    {        //获取SIM卡CIMI号码(SIM卡唯一id,必须存在)        if(SIMCOM_GetCIMI(pHandle, pHandle->SIM_CIMI) == TRUE) break;                SIMCOM_WaitSleep(pHandle, 100);        SIMCOM_Ready(pHandle);        pHandle->pDelayMS(1000);            //等待1s钟    }    if(i==retry) return FALSE;         return TRUE;}[url=][/url]

//SIMCOM_USER.h
[url=][/url]
/************************************************************************************************************* * 文件名:            SIMCOM_USER.h * 功能:            SIMCOM用户层函数 * 作者:            cp1300@139.com * 创建时间:        2015-02-15 * 最后修改时间:    2018-03-23 * 详细:            *************************************************************************************************************/#ifndef _SIMCOM_SUER_H_#define _SIMCOM_SUER_H_#include "system.h"#include "simcom.h" //SIMCOM 初始化错误typedef enum{    SIMCOM_INIT_OK                =    0,    //初始化成功        SIMCOM_POWER_UP_ERROR        =    1,    //上电错误    SIMCOM_REG_ERROR            =    2,    //注册出错(超时)    SIMCOM_INIT_ERROR            =    3,    //初始化配置错误    SIMCOM_SIM_NOT_REALYE        =    4,    //SIM卡未就绪导致上电失败    SIMCOM_NULL_ERROR            =    255    //状态无效}SIMCOM_USER_ERROR;  //API//初始化SIMCOM句柄接口bool SIMCOM_Init(SIMCOM_HANDLE *pHandle,        bool (* pSendData)(u8 *pDataBuff, u16 DataLen),                                            //发送数据接口,如果发送失败,返回FALSE,成功返回TRUE;        int (* pReadData)(u8 **pDataBuff, u8 ByteTimeOutMs, u16 TimeOutMs, u16 *pReceiveDelay),    //接收数据接口,返回数据长度,如果失败返回<=0,成功,返回数据长度        void (*pClearRxData)(void),                                                                //清除接收缓冲区函数,用于清除接收数据缓冲区数据        void (*pSetDTR_Pin)(u8 Level),                                                            //DTR引脚电平控制-用于控制sleep模式或者退出透传模式        void (*pSetPWRKEY_Pin)(u8 Level),                                                        //PWRKEY开机引脚电平控制-用于开机        u8 (*pGetSTATUS_Pin)(void),                                                                //获取STATUS引脚电平-用于指示模块上电状态        u8 (*pGetDCD_Pin)(void),                                                                //获取DCD引脚电平-高电平AT指令模式,低电平为透传模式        void (*pDelayMS)(u32 ms),                                                                //系统延时函数        void (*pIWDG_Feed)(void)                                                                //清除系统看门狗(可以为空)    );        SIMCOM_USER_ERROR SIMCOM_RegisNetwork(SIMCOM_HANDLE *pHandle, u16 Retry, u16 NetworkDelay,const char **pModeInof);//SIMCOM模块上电初始化并注册网络bool SIMCOM_PhoneMessageNumberInitialize(SIMCOM_HANDLE *pHandle, u8 retry);                        //SIMCOM 初始化获取短信中心号码以及本机号码,信号强度,CIMI(结果存放在句柄pHandle中)   #endif /*_SIMCOM_SUER_H_*/[url=][/url]

//底层相关接口,自己根据自己的平台进行开发的接口
[url=][/url]
//发送数据接口static bool GPRS_UART_SendData(u8 DataBuff[], u16 DataLen){    UARTx_SendData(SIMCOM_UART_CH, DataBuff, DataLen);        return TRUE;}   //接收数据接口static int GPRS_UART_ReadData(u8 **pDataBuff,u8 ByteTimeOutMs, u16 TimeOutMs, u16 *pReceiveDelayMs){    u32 cnt = 0;    u16 TempTime;        if(ByteTimeOutMs < 1) ByteTimeOutMs = 1;    //字节超时时间,2个帧之间的间隔最小时间    TimeOutMs /= ByteTimeOutMs;    TimeOutMs += 1;    TempTime = TimeOutMs;    while(TimeOutMs --)    {        cnt = UARTx_GetRxCnt(SIMCOM_UART_CH);        OSTimeDlyHMSM(0,0,0,ByteTimeOutMs);;        if((cnt > 0) && (cnt == UARTx_GetRxCnt(SIMCOM_UART_CH)))        {            if(pReceiveDelayMs!=NULL)    //需要返回延时            {                *pReceiveDelayMs = (TempTime-TimeOutMs)*ByteTimeOutMs;            }            *pDataBuff = g_SIMCOM_Buff;                        //接收缓冲区                        return cnt;        }#if SYS_WDG_EN_        IWDG_Feed();                                        //喂狗#endif                }        return 0;}  //清除接收缓冲区static void GPRS_UART_ClearData(void){    UARTx_ClearRxCnt(SIMCOM_UART_CH);    //清除串口缓冲区}[url=][/url]

[url=][/url]
///////////////////////////////////////////////////////////////////////////////////////////////SIM900/SIM800通信支持//GSM模块相关定义#define SIMCOM_UART_CH            UART_CH3            //串口3#define SIMCOM_UART_BAUD        115200                //波特率#define SIMCOM_UART_BUFF_SIZE    (1024*4)            //接收缓冲区大小 //相关控制引脚__inline void SIMCOM_SetDTR(u8 Level)        {(PGout(4)=Level);}            //DTR__inline void SIMCOM_SetPWRKEY(u8 Level)    {(PGout(3)=Level);}            //PWRKEY__inline u8 SIMCOM_GetSTATUS(void)            {return PGin(5)?1:0;}        //STATUS__inline u8 SIMCOM_GetDCD(void)                {return PDin(11)?1:0;}        //DCD-上拉输入,高电平AT指令模式,低电平为透传模式 //引脚初始化__inline void SIMCOM_IO_Init(void)    {    SYS_DeviceClockEnable(DEV_GPIOD, TRUE);                    //使能GPIOD时钟    SYS_DeviceClockEnable(DEV_GPIOG, TRUE);                    //使能GPIOG时钟    SYS_GPIOx_Init(GPIOG, BIT3|BIT4, OUT_PP, SPEED_2M);        //推挽输出    SYS_GPIOx_OneInit(GPIOD, 11, IN_IPU, IN_NONE);            //DCD 上拉输入    SYS_GPIOx_OneInit(GPIOG, 5, IN_IPD, IN_NONE);            //STATUS 下拉输入}  [url=][/url]

另外还有一个看门狗清除的回调函数
//喂独立看门狗__inline void IWDG_Feed(void) {IWDG->KR=0XAAAA;}

//实现了以上的接口就可以调用了

//下面是应用层调用,使用了ucos的一个任务

[url=][/url]
SIMCOM_HANDLE    g_SIMCOM_Handle;                                //SIMCOM通信模块句柄u8 g_SIMCOM_Buff[SIMCOM_UART_BUFF_SIZE+1];                        //串口接收缓冲区   static bool GPRS_UART_SendData(u8 DataBuff[], u16 DataLen);        //发送数据接口static int GPRS_UART_ReadData(u8 **pDataBuff,u8 ByteTimeOutMs, u16 TimeOutMs, u16 *pReceiveDelayMs);        //接收数据接口static void GPRS_UART_ClearData(void);                            //清除接收缓冲区  //GPRS通信任务void GPRS_Task(void *pdata){    const char *pModeInof;            UARTx_Init(SIMCOM_UART_CH, SIMCOM_UART_BAUD, ENABLE);                                                    //初始化串口    UARTx_SetRxBuff(SIMCOM_UART_CH, g_SIMCOM_Buff,  SIMCOM_UART_BUFF_SIZE);                                    //设置串口接收缓冲区    SIMCOM_IO_Init();                                                                                        //SIMCOM相关IO初始化    OSTimeDlyHMSM(0,0,0,20);        //初始化SIMCOM句柄接口    SIMCOM_Init(&g_SIMCOM_Handle,        GPRS_UART_SendData,        //发送数据接口,如果发送失败,返回FALSE,成功返回TRUE;        GPRS_UART_ReadData,        //接收数据接口,返回数据长度,如果失败返回<=0,成功,返回数据长度        GPRS_UART_ClearData,    //清除接收缓冲区函数,用于清除接收数据缓冲区数据        SIMCOM_SetDTR,            //DTR引脚电平控制-用于控制sleep模式或者退出透传模式        SIMCOM_SetPWRKEY,        //PWRKEY开机引脚电平控制-用于开机        SIMCOM_GetSTATUS,        //获取STATUS引脚电平-用于指示模块上电状态        SIMCOM_GetDCD,            //DCD-上拉输入,高电平AT指令模式,低电平为透传模式        SYS_DelayMS,            //系统延时函数        IWDG_Feed                //清除系统看门狗(可以为空)    );            while(1)    {        SIMCOM_RegisNetwork(&g_SIMCOM_Handle, 6, 60, &pModeInof);//SIMCOM模块上电初始化并注册网络        //SIMCOM 初始化获取短信中心号码以及本机号码,信号强度,CIMI(结果存放在句柄pHandle中)        if(SIMCOM_PhoneMessageNumberInitialize(&g_SIMCOM_Handle, 3) == FALSE)        {            uart_printf("\r\n警告:初始化获取相关信息失败!\r\n");        }                        OSTimeDlyHMSM(0,5,0,20);    }}[url=][/url]

//以上代码实现了通信模块的初始化,开机,联网,读取本机号码,中心站号码,SIMI码,信号等操作,感兴趣的朋友可以依照此模板进行后续的开发,使用底层分离的方式可以让代码解耦便于在各个平台上面移植,同时增加了稳定性。

//下面是串口打印的信息,命令执行的很快,我使用的是SIM7600CE模块,全网通4G,初始化非常快,每个文件都有定义调试开关,可以动态使用一个变量控制开关,也可以使用宏定义控制调试信息开关。

[url=][/url]
SIMCOM(26B)-&gt;SIMCOM_SIM7600CE OK OK 返回成功![DTU]通信模块为SIM7600 SIMCOM(22B)-&gt;+CPIN: READY OK OK 返回成功! SIM卡准备就绪! SIMCOM(20B)-&gt;+CREG: 0,1 OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功![DTU]网络注册状态1! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(22B)-&gt;+CPIN: READY OK OK 返回成功! SIM卡准备就绪! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(35B)-&gt;OK SIMCOM INCORPORATED OK OK 返回成功! SIMCOM(26B)-&gt;SIMCOM_SIM7600CE OK OK 返回成功! SIMCOM(34B)-&gt;+GMR: LE11B02SIM7600CE-A OK OK 返回成功! SIMCOM(25B)-&gt;861477030032237 OK OK 返回成功! 制造商:OK模块型号:SIMCOM_SIM7600CE软件版本E11B02SIM7600CE-A模块序列号:861477030032237 SIMCOM(42B)-&gt;+COPS: 0,0,"CHINA MOBILE CMCC",7 OK OK 返回成功!运营商信息:CHINA MOBILE CMCC SIMCOM(22B)-&gt;+CNSMOD: 0,8 OK OK 返回成功!网络制式TE SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(6B)-&gt;OK OK 返回成功! SIMCOM(37B)-&gt;+CSCA: "+8613800100569",145 OK OK 返回成功!短信中心号码:13800100569短信中心号码:13800100569 SIMCOM(21B)-&gt;+CSQ: 20,99 OK OK 返回成功!信号强度 &lt;20&gt;! SIMCOM(41B)-&gt;+CNUM: "","1064838905852",129  OK OK 返回成功!本机号码:1064838905852本机号码:1064838905852 SIMCOM(25B)-&gt;460040389005852 OK OK 返回成功!获取CIMI成功:460040389005852[url=][/url]




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

18

主题

99

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2016-1-20
在线时间
89 小时
 楼主| 发表于 2019-10-31 09:58:56 | 显示全部楼层
原子哥 帮忙把这个贴子删了,格式没有弄好
回复 支持 反对

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2016-5-23
在线时间
6 小时
发表于 2019-12-23 17:16:29 | 显示全部楼层
求源码,请大神提供下这个例程的相关源码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-3-13 23:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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