SIM800/SIM900/SIM7000/SIM7600底層操作接口_句柄方式完全分離通信底層
[導(dǎo)讀]使用SIMCOM公司通信模塊已經(jīng)好幾年了,周末抽空把底層重新寫(xiě)了,將底層的通信與應(yīng)用完全進(jìn)行了分離,便于移植。SIMCOM.h //定義了相關(guān)的結(jié)構(gòu)體與類(lèi)型。SIMCOM_AT.c//定義了底層的AT
使用SIMCOM公司通信模塊已經(jīng)好幾年了,周末抽空把底層重新寫(xiě)了,將底層的通信與應(yīng)用完全進(jìn)行了分離,便于移植。
SIMCOM.h //定義了相關(guān)的結(jié)構(gòu)體與類(lèi)型。
SIMCOM_AT.c//定義了底層的AT接口
SIMCOM_GSM.c//需要的模塊GSM相關(guān)命令
SIMCOM_GPRS.c//上網(wǎng)相關(guān)-未移植
SIMCOM_SMS.c//短信收發(fā)相關(guān)-未移植
SIMCOM_USER.c//用戶(hù)最終接口
//需要自己實(shí)現(xiàn)數(shù)據(jù)收發(fā)相關(guān)接口,DCD,DTR,PWRKEY,STATUS相關(guān)IO接口,需要一個(gè)ms延時(shí)支持
//SIMCOM.h
/*************************************************************************************************************
* 文件名: SIMCOM.h
* 功能: SIMCOM 底層定義
* 作者: cp1300@139.com
* 創(chuàng)建時(shí)間: 2015-02-15
* 最后修改時(shí)間: 2018-03-23
* 詳細(xì): 注意:底層通信接口使用的是回調(diào)函數(shù),但是必須提供系統(tǒng)延時(shí)函數(shù) void SYS_DelayMS(u32 ms);
*************************************************************************************************************/
#ifndef _SIMCOM_H_
#define _SIMCOM_H_
#include "system.h"
//SIMCOM通信模塊定義
typedef enum
{
SIMCOM_SIM900 = 0 , //默認(rèn)為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 , //無(wú)效則默認(rèn)
}SIMCOM_MODE_TYPE;
//網(wǎng)絡(luò)注冊(cè)狀態(tài)
typedef enum
{
SIMCOM_NET_NOT = 0, //未注冊(cè)
SIMCOM_NET_YES = 1, //已經(jīng)注冊(cè)
SIMCOM_NET_SEA = 2, //未注冊(cè),正在搜索
SIMCOM_NET_TUR = 3, //注冊(cè)被拒絕
SIMCOM_NET_UNK = 4, //未知
SIMCOM_NET_ROA = 5, //已經(jīng)注冊(cè),但是漫游
SIMCOM_NET_ERROR=0XFF //錯(cuò)誤
}SIMCOM_NETSTATUS;
//SIMCOM網(wǎng)絡(luò)制式
typedef enum
{
SIMCOM_NETMODE_NOT = 0, //未注冊(cè)
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也是這個(gè))
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卡就緒狀態(tài)
typedef enum
{
SIM_READY = 0, //SIM卡就緒
SIM_NOT_READY = 1, //SIM卡未就緒
SIM_UNKNOWN = 2 //SIM卡狀態(tài)未知
}SIM_CARD_STATUS;
//控制IO電平定義
#define SIMCOM_H_LEVEL 1 //高電平
#define SIMCOM_L_LEVEL 0 //低電平
//DCD狀態(tài)定義
#define DCD_DATA_MODE 0 //數(shù)據(jù)透?jìng)髂J?#define DCD_AT_MODE 1 //AT指令模式
//相關(guān)信息長(zhǎng)度限制
#define SIMCOM_INFO_SIZE 24 //信息長(zhǎng)度
#define SIMCOM_VER_SIZE 24 //軟件版本長(zhǎng)度定義
//重試次數(shù),防止AT指令操作失敗
#define SIMCOM_DEFAULT_RETRY 2
//SIMCOM模塊相關(guān)信息
typedef struct
{
char Manu[SIMCOM_INFO_SIZE+1]; //制造商
char Model[SIMCOM_INFO_SIZE+1]; //型號(hào)
char Ver[SIMCOM_VER_SIZE+1]; //軟件版本
char IMEI[SIMCOM_INFO_SIZE+1]; //序列號(hào)
}SIMCOM_INFO;
//NBIOT模式定義
typedef enum
{
NB_IOT_MODE = 0, //NBIOT模式
CAT_M_MODE = 1, //CAT-M模式
}NBIOT_MODE_TYPE;
//網(wǎng)絡(luò)模式設(shè)置
typedef struct
{
SIMCOM_MODE_TYPE ModeType; //模塊型號(hào)
NBIOT_MODE_TYPE NB_Mode; //NB模式
s8 NB_EnableMode; //NB模式使能模式,-1:無(wú)需設(shè)置;0:關(guān)閉NB,使能GSM模式;1:使能NB模式
bool isNB_ScarEnable; //NB模式擾碼使能
}NETWORK_CONFIG_TYPE;
//SIMCOM通信模塊句柄
typedef struct
{
//所需變量
SIMCOM_MODE_TYPE SimcomModeType; //模塊型號(hào)
char TelecomCarr[SIMCOM_INFO_SIZE+1]; //運(yùn)營(yíng)商名稱(chēng)
SIMCOM_INFO SIMCOM_Info; //SIMCOM通信模塊相關(guān)信息結(jié)構(gòu)體
NETWORK_CONFIG_TYPE NetworkConfig; //網(wǎng)絡(luò)模式設(shè)置
SIMCOM_NETMODE_TYPE NetworkMode; //當(dāng)前網(wǎng)絡(luò)制式
u8 Singal; //網(wǎng)絡(luò)信號(hào)強(qiáng)度
char LocalPhoneNumber[16]; //本機(jī)電話(huà)號(hào)碼
char ServiceCenterPhoneNumber[16]; //短信中心電話(huà)號(hào)碼
char SIM_CIMI[16]; //SIM卡唯一CIMI號(hào)碼
//底層通信接口
bool (* pSendData)(u8 *pDataBuff, u16 DataLen); //發(fā)送數(shù)據(jù)接口,如果發(fā)送失敗,返回FALSE,成功返回TRUE;
int (* pReadData)(u8 **pDataBuff, u8 ByteTimeOutMs, u16 TimeOutMs, u16 *pReceiveDelay); //接收數(shù)據(jù)接口,返回?cái)?shù)據(jù)長(zhǎng)度,如果失敗返回<=0,成功,返回?cái)?shù)據(jù)長(zhǎng)度
void (*pClearRxData)(void); //清除接收緩沖區(qū)函數(shù),用于清除接收數(shù)據(jù)緩沖區(qū)數(shù)據(jù)
void (*pSetDTR_Pin)(u8 Level); //DTR引腳電平控制-用于控制sleep模式或者退出透?jìng)髂J? void (*pSetPWRKEY_Pin)(u8 Level); //PWRKEY開(kāi)機(jī)引腳電平控制-用于開(kāi)機(jī)
u8 (*pGetSTATUS_Pin)(void); //獲取STATUS引腳電平-用于指示模塊上電狀態(tài)
u8 (*pGetDCD_Pin)(void); //獲取DCD引腳電平-高電平AT指令模式,低電平為透?jìng)髂J? //系統(tǒng)接口
void (*pDelayMS)(u32 ms); //系統(tǒng)延時(shí)函數(shù)
void (*pIWDG_Feed)(void); //清除系統(tǒng)看門(mén)狗(可以為空)
//內(nèi)部狀態(tài)定義
bool s_isInitStatus; //用于記錄模塊初始化狀態(tài),復(fù)位或上電后變?yōu)闊o(wú)效
}SIMCOM_HANDLE;
#endif /*_SIMCOM_H_*/
//SIMCOM_AT.c
/*************************************************************************************************************
* 文件名: SIMCOM_AT.c
* 功能: SIMCOM底層AT指令接口
* 作者: cp1300@139.com
* 創(chuàng)建時(shí)間: 2015-02-15
* 最后修改時(shí)間: 2018-03-23
* 詳細(xì):
*************************************************************************************************************/
#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指令調(diào)試狀態(tài)
//調(diào)試開(kāi)關(guān)
#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
/*************************************************************************************************************************
* 函數(shù) : bool SIMCOM_SendAT(SIMCOM_HANDLE *pHandle, char *pStr)
* 功能 : 發(fā)送一個(gè)AT指令(會(huì)添加結(jié)束符rn),不會(huì)等待響應(yīng)
* 參數(shù) : pHandle:SIMCOM句柄;pStr:指令字符串
* 返回 : 接口發(fā)送狀態(tài)
* 依賴(lài) : 無(wú)
* 作者 : cp1300@139.com
* 時(shí)間 : 2018-03-23
* 最后修改時(shí)間 : 2018-03-23
* 說(shuō)明 : 用于底層AT指令發(fā)送
*************************************************************************************************************************/
bool SIMCOM_SendAT(SIMCOM_HANDLE *pHandle, char *pStr)
{
pHandle->pSendData((u8 *)pStr, strlen(pStr)); //發(fā)送指令
return pHandle->pSendData((u8 *)"rn", 2); //發(fā)送結(jié)束符
}
/*************************************************************************************************************************
* 函數(shù) : bool SIMCOM_TestAT(SIMCOM_HANDLE *pHandle, u32 retry)
* 功能 : SIMCOM AT 命令通信測(cè)試
* 參數(shù) : pHandle:SIMCOM句柄;retry:重試次數(shù)
* 返回 : FALSE:通信失敗;TRUE:通信成功
* 依賴(lài) : 底層
* 作者 : cp1300@139.com
* 時(shí)間 : 2013-10-20
* 最后修改時(shí)間 : 2018-03-23
* 說(shuō)明 : 每隔100ms向SIMCOM通信模塊發(fā)送一個(gè)"AT",等待響應(yīng)返回
*************************************************************************************************************************/
bool SIMCOM_TestAT(SIMCOM_HANDLE *pHandle, u32 retry)
{
u32 cnt;
u8 *pRxBuff;
//檢測(cè)模塊存在
do
{
SIMCOM_SendAT(pHandle, "AT"); //發(fā)送"AT",同步波特率,并且等待應(yīng)答
pHandle->pClearRxData(); //清除計(jì)數(shù)器
if(AT_RETURN_OK == SIMCOM_GetATResp(pHandle, &pRxBuff, &cnt, "OK", 10, 150)) //等待響應(yīng),超時(shí)150ms
{
pHandle->pDelayMS(100);
return TRUE;
}
retry --;
}while(retry);
pHandle->pDelayMS(100);
return FALSE;
}
/*************************************************************************************************************************
* 函數(shù) : bool SIMCOM_WaitSleep(SIMCOM_HANDLE *pHandle, u32 TimeOutMs)
* 功能 : 等待模塊空閑,并重新喚醒
* 參數(shù) : pHandle:句柄;TimeOut:等待超時(shí),時(shí)間單位ms
* 返回 : TRUE:成功;FALSE:超時(shí)
* 依賴(lài) : 無(wú)
* 作者 : cp1300@139.com
* 時(shí)間 : 2013-10-25
* 最后修改時(shí)間 : 2018-03-24
* 說(shuō)明 : 用于等待操作完成,防止快速操作造成模塊不響應(yīng)
*************************************************************************************************************************/
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); //等待模塊空閑后進(jìn)入SLEEP模式
//循環(huán)發(fā)送命令,直到命令超時(shí)了則認(rèn)為進(jìn)入了sleep模式
for(i = 0;i < (TimeOutMs/100);i ++)
{
pHandle->pDelayMS(100); //延時(shí)100ms
SIMCOM_SendAT(pHandle, "AT"); //發(fā)送"AT",同步波特率,并且等待應(yīng)答
pHandle->pClearRxData(); //清除接收計(jì)數(shù)器
if(AT_RETURN_TIME_OUT == SIMCOM_GetATResp(pHandle, &pData, &cnt, "OK", 10, 100)) //等待響應(yīng),超時(shí)100ms
{
break;
}
}
pHandle->pSetDTR_Pin(SIMCOM_L_LEVEL); //喚醒
if(i == (TimeOutMs/100))
{
SIMCOM_debug("模塊進(jìn)入空閑模式失敗!rn");
pHandle->pClearRxData(); //清除接收計(jì)數(shù)器
return FALSE;
}
pHandle->pDelayMS(100); //延時(shí)100ms
SIMCOM_debug("模塊進(jìn)入空閑模式成功!rn");
SIMCOM_TestAT(pHandle, 10);
pHandle->pClearRxData(); //清除接收計(jì)數(shù)器
return TRUE;
}
/*************************************************************************************************************************
* 函數(shù) : SIMCOM_AT_ERROR SIMCOM_GetATResp(SIMCOM_HANDLE *pHandle, u8 **pRxBuff, u32 *pLen, const char *pKeyword, u8 ByteTimeOutMs, u16 TimeOutMs)
* 功能 : 獲取SIMCOM的AT指令響應(yīng)
* 參數(shù) : pHandle:句柄
pRxBuff:接收緩沖區(qū)指針(輸出);pLen:接收到的數(shù)據(jù)大小(輸出),
pKeyword:關(guān)鍵字,為字符串,比如"OK",如果在接收到的字符串中有OK字符,就返回成功,否則失敗(輸入)
ByteTimeOutMs:字節(jié)超時(shí)時(shí)間,單位ms最大255ms
TimeOutMs:等待超時(shí)時(shí)間,單位毫秒
* 返回 : SIM900_ERROR
* 依賴(lài) : 無(wú)
* 作者 : cp1300@139.com
* 時(shí)間 : 2018-03-24
* 最后修改時(shí)間 : 2018-03-24
* 說(shuō)明 : 本函數(shù)會(huì)在接收緩沖區(qū)字符串結(jié)束添加'