本来是想在这里记录开发工作中遇到的问题,有时候太忙就忘记这回事了。
之前使用SIMCOM的GSM模块现在通信显得有点吃力,毕竟很多地方2G通信不是很顺畅,速率也跟不上。最近在使用SIMCOM的4G模块,更能满足现在数据通信的要求,毕竟现在5G都宣传挺久了。
底层大部分还是沿用之前的,有做一些改动。
SIM7600CE支持LTE-TDD/LTE-FDD/HSPA+/TD-SCDMA/EVDO和GSM/GPRS/EDGE等频段, 支持LTE CAT4(下行速度为150Mbps),有LCC封装和PCIE封装,两者引脚有些差异,这次使用的PCIE封装有些引脚没有引出来。具体差异可参考官方手册。
没有用于指示模块上电状态的STATUS引脚,直接由硬件控制模块上电和掉电并程序记录上电状态。上电初始化过程注释掉之前的检测模块上电状态的部分。
void SIMCOM_SetPWRKEY(uint8_t Level)
{
if(Level) HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11,GPIO_PIN_SET);
else HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11,GPIO_PIN_RESET);
} //PWR
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) //上电
// {
// pHandle->pSetPWRKEY_Pin(SIMCOM_H_LEVEL);
// pHandle->pDelayMS(500);
// 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; //开机失败
// }
// }
SIM7600CE和GSM模块有部分AT指令不通用,需要注意。比如获取模块相关信息的内容需要做修改。
/*************************************************************************************************************************
* 函数 : uint8_t SIMCOM_GetModuleInfo(SIMCOM_HANDLE *pHandle, SIMCOM_INFO *pInfo)
* 功能 : 获取模块的相关信息
* 参数 : pHandle:句柄;pInfo:信息结构体指针
* 返回 : 0:失败;1:成功
* 依赖 : 底层
* 作者 :
* 时间 : 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
*************************************************************************************************************************/
uint8_t SIMCOM_GetModuleInfo(SIMCOM_HANDLE *pHandle, SIMCOM_INFO *pInfo)
{
uint32_t i,cnt;
uint8_t retry = SIMCOM_DEFAULT_RETRY; //重试次数
char *p;
uint8_t *pData;
//清空缓冲区
pInfo->Manu[0] = 0;
pInfo->Model[0] = 0;
pInfo->Ver[0] = 0;
pInfo->IMEI[0] = 0;
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[i] = pData[2+i];
}
pInfo->Model[i] = 0;
break;
}
SIMCOM_Ready(pHandle); //等待就绪
pHandle->pDelayMS(1000); //失败延时1秒后重试
retry --;
}while(retry);
if(retry == 0) return 0;
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[i] == '\r') || (p[i] == '\n') || (p[i] == '\0')) break;
pInfo->Ver[i] = p[i];
}
pInfo->Ver[i] = 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[i] = pData[2+i];
}
pInfo->Ver[i] = 0;
}
break;
}
SIMCOM_Ready(pHandle); //等待就绪
pHandle->pDelayMS(1000); //失败延时1秒后重试
retry --;
}while(retry);
if(retry == 0) return 0;
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[i] = pData[2+i];
}
pInfo->IMEI[i] = 0;
break;
}
SIMCOM_Ready(pHandle); //等待就绪
pHandle->pDelayMS(1000); //失败延时1秒后重试
retry --;
}while(retry);
return 1;
}
初始化和网络注册成功之后与远端服务器进行TCP连接,SIM7600CE同样支持透传模式,在模块初始化中开启透传模式
retry = SIMCOM_DEFAULT_RETRY; //重试次数
do
{
if( SIMCOM_SetParametersReturnbool(pHandle, "AT+CIPMODE=1", SIMCOM_DEFAULT_RETRY, 2000, "开启透传模式失败!\r\n"))
{
break;
}
retry --;
}while(retry);
之后再进行TCP服务器的连接,连接过程使用的AT指令
AT+CGDCONT=1 设置CMNET
AT+NETOPEN 建立无线链路
AT+CIPOPEN 建立TCP连接
/*************************************************************************************************************************
* 函数 : uint8_t SIMCOM_Establish_Socket(SIMCOM_HANDLE *pHandle)
* 功能 : 连接TCP服务器函数
* 参数 :
* 返回 : 连接建立状态
* 依赖 : 无
* 作者 :
* 时间 : 2018-12-23
* 最后修改时间 : 2018-12-23
* 说明 :
*************************************************************************************************************************/
int RSSI_sim=0;
tcp_udp_dev TcpUdpDev;
uint8_t SIMCOM_Establish_Socket(SIMCOM_HANDLE *pHandle)
{
uint8_t retry;
char Server[100];
//配置服务器IP地址 格式: "AT+CIPOPEN=0,\"TCP\",\"47.106.137.199\",20000"
sprintf(Server,"AT+CIPOPEN=0,\"TCP\",\"%d.%d.%d.%d\",%d",TcpUdpDev.remoteip[0],TcpUdpDev.remoteip[1],TcpUdpDev.remoteip[2],TcpUdpDev.remoteip[3],TcpUdpDev.remoteport);
printf("%s",Server);
// const char *Server = "AT+CIPOPEN=0,\"TCP\",\"47.92.243.219\",12351"; //IP登录服务器
retry = SIMCOM_DEFAULT_RETRY;
while(retry)
{
if(SIM800_GetGPRSAdhereStatus(pHandle)!=1)
{
}
else break;
pHandle->pDelayMS(1000); //延时1秒
retry --;
}
if(retry==0)
{
printf("\r\nGPRS附着失败\r\n");
return 0;
}
RSSI_sim = SIMCOM_GetSignal(pHandle); //获取信号强度
pHandle->Singal = (uint8_t)RSSI_sim;
#if SIMCOM_USER_DBUG
printf("信号强度 <%02d>!\r\n" ,RSSI_sim);
#endif
if(SIMCOM_SetParametersReturnbool(pHandle, "AT+CGDCONT=1,\"IP\",\"CMNET\"", 1, 510, "\r\n设置为CMNET失败\r\n") == 0)return 0;
if(SIMCOM_SetParametersReturnbool(pHandle, "AT+NETOPEN", 1, 510, "\r\n 建立无线链路失败\r\n") == 0);
// LED2_OFF();
// SIMCOM_SetParametersReturnbool(pHandle, "AT+CIFSR", 0, 510, "\r\n");
// SIMCOM_SetParametersReturnbool(&g_SIMCOM_Handle,"AT+CIPCLOSE=0", 0, 510, "\r\n删除TCP连接失败\r\n");
if(SIMCOM_SetConnectReturnbool(pHandle,(char*)Server, 1, 510, "\r\n建立TCP连接失败\r\n") == 0)return 0;
// LED2_ON();
return 1;
}
连接过程中遇到一个问题:
如果远端服务器主动断开TCP连接,模块删除连接后再次建立连接不成功,显示连接已经存在,重启系统后能正常建立连接
/*************************************************************************************************************************
* 函数 : uint8_t SIMCOM_Delete_Socket(SIMCOM_HANDLE *pHandle)
* 功能 : 连接UDP服务器函数
* 参数 :
* 返回 : 删除连接
* 依赖 : 无
* 作者 :
* 时间 : 2018-12-23
* 最后修改时间 : 2018-12-23
* 说明 :
*************************************************************************************************************************/
uint8_t SIMCOM_Delete_Socket(SIMCOM_HANDLE *pHandle)
{
char Server[50];
uint8_t retry;
sprintf(Server,"AT+CIPCLOSE=0");
// TcpUdpDev.socketid++;
// if(TcpUdpDev.socketid>9)TcpUdpDev.socketid=0;
if(SIMCOM_SetParametersRetbool(pHandle, "+++", 3, 4000,"OK","关闭透传模式失败!\r\n") == 0);
if(SIMCOM_SetParametersReturnbool(pHandle,(char*)Server, 1, 510, "\r\n删除TCP连接失败\r\n")== 0);
if(SIMCOM_SetParametersReturnbool(pHandle, "AT+NETCLOSE", 1, 510, "\r\n 删除无线链路失败\r\n") == 0);
// LED2_ON();
return 1;
}