当前位置:首页 > 芯闻号 > 充电吧
[导读]使用SIMCOM公司通信模块已经好几年了,周末抽空把底层重新写了,将底层的通信与应用完全进行了分离,便于移植。SIMCOM.h //定义了相关的结构体与类型。SIMCOM_AT.c//定义了底层的AT

使用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

/*************************************************************************************************************
 * 文件名:			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_*/

//SIMCOM_AT.c

/*************************************************************************************************************
 * 文件名:			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指令(会添加结束符rn),不会等待响应
* 参数				:	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 *)"rn", 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("模块进入空闲模式失败!rn");
		pHandle->pClearRxData();				//清除接收计数器
		
		return FALSE;
	}
	pHandle->pDelayMS(100);				//延时100ms
	
	SIMCOM_debug("模块进入空闲模式成功!rn");
	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
* 说明				: 	本函数会在接收缓冲区字符串结束添加''
						本函数不能清除缓冲区
*************************************************************************************************************************/
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]	= '';													//将数据结尾添加结束字符串
	}
	
	SIMCOM_debug("rnSIMCOM(%dB)->%srn",len, *pRxBuff);						//打印返回信息
	if(strstr((const char*)(*pRxBuff), pKeyword) != NULL) 	//搜索关键字
	{
		SIMCOM_debug("%s 返回成功!rn",pKeyword);
	    return AT_RETURN_OK;
	}
	else if(strstr((const char*)(*pRxBuff), "ERROR") != NULL)
	{
		SIMCOM_debug("%s 返回错误!rn",pKeyword);
		return AT_RETURN_ERROR;
	}
	else
	{
		SIMCOM_debug("%s 返回未知!rn",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[i];
		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[i] = 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[i] - '0';
		if(temp > 9)			//只能是数字范围
			return 0;
		for(j = 1;j < (NumDigits - i);j ++)
		{
			temp *= 10;
		}
		DEC += temp;
	}
	return DEC;
}

//SIMCOM_AT.h

/*************************************************************************************************************
 * 文件名:			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指令(会添加结束符rn),不会等待响应
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指令(会添加结束符rn),不会等待响应
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*/

//SIMCOM_GSM.c //通用的底层操作

/*************************************************************************************************************
 * 文件名:			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 

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网络模式!rn");
				if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CNMP=13", SIMCOM_DEFAULT_RETRY, 200, "rn设置SIM7000C GSM模式失败!rn") == FALSE) return FALSE; //GSM模式
			}break;
			case 1://NB模式
			{
				uart_printf("[DTU]设置NBIOT网络模式!rn");
				if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CNMP=38", SIMCOM_DEFAULT_RETRY, 200, "rn设置SIM7000C LTE NB模式失败!rn") == 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, "rn设置SIM7000C CAT NB模式失败!rn") == 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, "rn设置SIM7000C NB 扰码模式失败!rn") == 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, "开启透传模式失败!rn");	//开启透传模式
	
	//设置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发送数据缓冲区设置失败!rn");	//发送	
}



/*************************************************************************************************************************
* 函数				:	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, "rn关闭Call Ready显示失败!rn");
		}break;
		default:break;
	}
	//设置关闭回显
	if(SIMCOM_SetParametersReturnBool(pHandle, "ATE 0", SIMCOM_DEFAULT_RETRY, 110, "rn关闭AT回显模式失败!rn") == FALSE)
	{
		return FALSE;
	}
	//设置短消息格式为PDU格式
	if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CMGF=0", SIMCOM_DEFAULT_RETRY, 110, "rn设置短消息格式为PDU格式失败!rn") == FALSE)
	{
		uart_printf("rn设置DCD功能模式失败!rn");
		return FALSE;
	}
	//设置DCD功能模式,DCD线只在数据载波存在时为ON。
	if(SIMCOM_SetParametersReturnBool(pHandle, "AT&C1", SIMCOM_DEFAULT_RETRY, 110, "rn设置DCD功能模式失败!rn") == FALSE)
	{
		uart_printf("rn设置DCD功能模式失败!rn");
		//return FALSE;
	}
	//设置 DTR 功能模式,DTR 由ON至OFF:TA在保持当前数据通话的同时,切换至命令模式
	if(SIMCOM_SetParametersReturnBool(pHandle, "AT&D1", SIMCOM_DEFAULT_RETRY, 110, "rn设置DTR功能模式失败!rn") == FALSE)
	{
		uart_printf("rn设置DTR功能模式失败!rn");
		//return FALSE;
	}
	
//	//使能RI引脚提示
//	if(SIM900_SetParametersReturnBool("AT+CFGRI=1", SIMCOM_DEFAULT_RETRY, 11, "rn启动RI引脚提示失败!rn") == FALSE)
//	{
//		return FALSE;
//	}
	
	//设置模块sleep模式使能//发送"AT+CSCLK",启动SLEEP模式;0:关闭;1:手动;2:自动空闲5S钟后休眠
	if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CSCLK=1", SIMCOM_DEFAULT_RETRY, 110, "rn设置SLEEP失败!rn") == FALSE)
	{
		return FALSE;
	}
	


	//检查卡是否就绪
	retry = 8;					//重试次数
	do
	{
		if(SIMCOM_GetCPIN(pHandle)==SIM_READY)
		{
			uart_printf("rnSIM卡准备就绪!rn");
			break;
		}
		else
		{
			uart_printf("rnSIM卡未准备就绪!rn");
		}
		
		SIMCOM_Ready(pHandle);						//等待就绪
		pHandle->pDelayMS(1000);					//失败延时1秒后重试
		retry --;
	}while(retry);
	if(retry == 0)
	{
		uart_printf("rnSIM卡未准备就绪!rn");
		pHandle->pClearRxData();					//清除接收计数器
		return FALSE;
	}
	
//	//上电删除所有短信
//	retry = SIMCOM_DEFAULT_RETRY;						//重试次数
//	do
//	{
//		if(SIM900_DelMultiSMS(DelSMS) == TRUE)//删除短信
//		{
//			//uart_printf("上电删除短信成功!rn");
//			break;
//		}
//		SIM900_Ready();	//等待就绪
//		retry --;
//	}while(retry);
//	if(retry == 0)
//	{
//		uart_printf("上电删除短信失败!rn");
//		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, "rn关闭新消息自动上报失败!rn") == 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, "rn配置TCP/IP失败!rn") == FALSE)
				{
					//return FALSE;
				}
				else break;
				pHandle->pDelayMS(1000);				//延时1秒
				retry --;
			}
			if(retry == 0)
			{
				uart_printf("rn设置TCP重发次数以及发送延时失败!rn");
				pHandle->pClearRxData();				//清除接收计数器
				return FALSE;
			}
			//设置不用等到发送响应
			retry = SIMCOM_DEFAULT_RETRY;			//重试次数
			while(retry)
			{
				//设置重试次数为3次,并且发送延时为120ms
				if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPSENDMODE=0", SIMCOM_DEFAULT_RETRY, 110, "rn不用等待发送ACK设置失败!rn") == FALSE)
				{
					//return FALSE;
				}
				else break;
				pHandle->pDelayMS(1000);				//延时1秒
				retry --;
			}
			if(retry == 0)
			{
				uart_printf("rn设置不用等待发送ACK失败!rn");
				pHandle->pClearRxData();				//清除接收计数器
			}
			
			//显示接收数据长度
			retry = SIMCOM_DEFAULT_RETRY;			//重试次数
			while(retry)
			{
				//设置重试次数为3次,并且发送延时为120ms
				if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPHEAD=1", SIMCOM_DEFAULT_RETRY, 110, "rn显示接收数据长度设置失败!rn") == FALSE)
				{
					//return FALSE;
				}
				else break;
				pHandle->pDelayMS(1000);				//延时1秒
				retry --;
			}
			if(retry == 0)
			{
				uart_printf("rn设置显示接收数据长度失败!rn");
				pHandle->pClearRxData();				//清除接收计数器
				return FALSE;
			}
			
			//不显示接收数据IP头
			retry = SIMCOM_DEFAULT_RETRY;		//重试次数
			while(retry)
			{
				//设置重试次数为3次,并且发送延时为120ms
				if(SIMCOM_SetParametersReturnBool(pHandle, "AT+CIPSRIP=0", SIMCOM_DEFAULT_RETRY, 110, "rn不显示接收数据IP头设置失败!rn") == FALSE)
				{
					//return FALSE;
				}
				else break;
				pHandle->pDelayMS(1000);				//延时1秒
				retry --;
			}
			if(retry == 0)
			{
				uart_printf("rn不显示接收数据IP头失败!rn");
				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("rn设置GPRS传输大小失败!rn");
				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("%srn",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] == '')) break;
					pInfo->Manu[i] = pData[2+i];
				}
				pInfo->Manu[i] = 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] == '')) 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 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("+        
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

SAP(思爱普)近日发出的裁员计划,不仅涉及全球范围内约8000个职位,更是在中国区造成了近1500名正式员工和合同工不续的情况。

关键字: 软件 互联网

业内消息,近日Alphabet旗下谷歌公司发言人表示为控制成本正在进行最新裁员,但具体人数不详。该发言人表示,裁员并非全公司范围,受影响的员工将能够申请内部职位,但没有具体说明受影响的员工人数或涉及的团队。

关键字: 谷歌 裁员

几天前,以南印度组织零售商协会(ORA)为代表的20多家零售连锁店和4300家商店宣布将从5月1日起停止销售一加设备。4月17日,全印度移动零售商协会(AIMRA)代表印度15万多家线下智能手机零售商通知一加,其成员正在...

关键字: 印度 一加 小米 Poco

业内消息,近日光刻机制造商阿斯麦(ASML)公布了2024年第一季度业绩,财报显示,该公司当季总净销售额53亿欧元,环比下降27%;毛利率51.0%,上季度为51.4%;净利润12亿欧元(当前约92.4亿元人民币),环比...

关键字: 光刻机 ASML

近日有韩媒称,由于薪资谈判破裂,劳资双方未能缩小对涨薪的意见分歧,三星电子全国工会(NSEU)即日起将发起公司成立以来首次集体行动,工会当天在华城市(Hwaseong)京畿道华城园区的组件研究大楼(DSR)前举行文化活动...

关键字: 三星

昨天上午,华为终端官微宣布全新重磅新机开售,约一分钟线上即告售罄,线下门店排起长队,气势丝毫不输苹果,和 Mate 60 Pro 一样没有发布会,这次官方同样推出了 “HUAWEI Pura 70 系列 先锋计划”,可以...

关键字: 麒麟芯片 华为

上海2024年4月16日 /美通社/ -- 4月14日,为期四天的第89届中国国际医疗器械博览会(CMEF)盛大收官。澳鹏Appen很荣幸再次作为唯一的人工智能训练数据参展商参与此次"航母级"规模医疗...

关键字: APP 医疗器械 PEN 模型

基于大语言模型研发的品牌定制化AI客服解决方案,获得业界高度认可 上海2024年4月16日 /美通社/ -- transcosmos集团(中文名:大宇宙集团;以下简称:transcosmos)于2024年4月11日在C...

关键字: TRANS TI COSMOS AI

针对光伏优化器(MPPT)的非隔离DC-DC升压电路,推荐瑞森半导体低压MOS-SGT系列。极低导通电阻,低损耗,高雪崩耐量,高效率,非常适合高频应用。

关键字: 光伏优化器 MPPT

IDC近日发布的全球智能手机市场初步数据显示,苹果iPhone全球销量在今年一季度的销量下降了9.6%。

关键字: iPhone 苹果 端侧AI
关闭
关闭