⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sms.c

📁 单片机W78E516B控制g18手机模块收发短消息
💻 C
字号:
#include<reg54.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/////////////////////////////////////////////////////////////
//|Function:int cal_crc
//| 16位CRC:按位计算,速度最慢,占用空间最少
//| 注:数据流是高位先行
//|输入:整数以及初始crc值
//|输出:按位计算的16位crc值,余式采用0x1021
//////////////////////////////////////////////////////////////
xdata char buf[128];




unsigned int cal_crc(unsigned int command,unsigned int crc){
 	
	unsigned int i;
 	
	crc=crc^(command<<8);
 	
	for(i=0; i<=7; i++) {
 		
		if((crc&0x8000)!=0)
    		crc=(crc<<1)^0x1021;
 		else 
    		crc=(crc<<1);
 	}
 	return crc;
}

//////////////////////////////////////////////////////////////////
//|Function:char *left
//|获得字符串子串,从走到右
//|
//|输入:字符串以及截取的长度
//| 
//|输出:子串的地址
//| 
//|Example:	char p[] = "TTTT1234";
//|				char t[5];
//|				t = left(p,4);		//Should Return "TTTT"
/////////////////////////////////////////////////////////////////////

char *left(const char *chString,unsigned int len)
{

	unsigned int i;				//Loop VAR
	int k, nIndex;				//More Loop VARs
//	char *buf;					//Temp String VARs


	if (!strlen(chString))						//If There Is No String
		return NULL;							//Return NULL

	if (len > strlen(chString))					//If The Amount To Copy Is Larger Than The String
		len = strlen(chString);					//Set The Length To The Length Of The String

//	buf = (char *)malloc(len + 1);

	//Copy The Part We Want From The Orginal String To The Result
	for (i = 0, nIndex = 0, k = 0; i < len; i++)	
	{		
		if (chString[nIndex] != '\0')			//If Not A NULL Char
			buf[k++] = chString[nIndex++];
		else
			break;
	}

	buf[k] = '\0';						//Add A NULL Char To The End Of The String

	return buf;
}

////////////////////////////////////////////////
//|Function:int  HexToInt
//|十六进制格式字符串转换为整数				
//|
//|输入:十六进制字符串
//|				
//|输出:转换后对应的整数数值,错误则返回-1              
//|
//| 
//| Example:    int result;
//|             char str[]="123";
//|             result=HexToInt(str);     //result=0x0123
///////////////////////////////////////////////

int HexToInt(char * Hexvalue){
	
	int i,tempint,len,sum=0;
	char buffer[2];
 	len=strlen(Hexvalue);
  	
	for(i=0;i<len;i++){
  		
		buffer[0]= Hexvalue[i];
  		buffer[1]='\0';
  		
		switch(buffer[0]){
   			case '0':
   			case '1':
   			case '2':
   			case '3':
   			case '4':
   			case '5':	
   			case '6':
   			case '7':
   			case '8':
   			case '9':tempint=atoi(buffer) ;break;
   			case 'a':
   			case 'A':tempint=10;break;
   			case 'b':
   			case 'B':tempint=11;break;
   			case 'c':
   			case 'C':tempint=12;break;
   			case 'd':
  			case 'D':tempint=13;break;
   			case 'e':
   			case 'E':tempint=14;break;
   			case 'f':
   			case 'F':tempint=15;break;
   			default :return -1;
   		}
   		sum=sum*16+tempint; 	
  	}
  	return sum;	
}
///////////////////////////////////////////////////////////////////////
//| Function:	BinaryFuse()
//|	二进制融合将输入的字符串按照每两位结合所代表的整数原则,转变为一半长度的整数数组				
//|
//|	输入:源字符串,起始位置,融合长度,目标数组,数据开始位置
//|
//|	返回:void		
//|
//| Example:    
//|             char str[]="1234";
//|             int  data[2];
//|             BinaryFuse(str,0,4,data,0); //data=0x2,0x12,0x34           
/////////////////////////////////////////////////////////////////////////

void BinaryFuse(unsigned char* Str,int SStart, int Len,unsigned int* Data,int DStart){
	
//	int i,charvalue;
	unsigned char i,charvalue;
 	char buffer[3];
 	if(DStart==0)
		Data[0]=Len/2;
 	else
   		Data[0]+=Len/2;
 	
	for(i=1;i<=Len/2;i++){
  		
		buffer[0]=Str[SStart+2*i-2];
  		buffer[1]=Str[SStart+2*i-1];
  		buffer[2]='\0';
  		charvalue=HexToInt(buffer);
  		
		if(charvalue>=0)
	 		Data[DStart+i]=charvalue;
  		else{
			//printf("BianryFuse String Error!");
			Data=NULL;		
			return ;	
		}	
  	}
}

/////////////////////////////////////////////////////////////////////////
//| Function:	unsigned char ParseString()
//|从源字符串中获取命令包、对命令包进行CRC校验、解析出命令单元的数据保存到目的数组
//|					
//|输入:源字符串,目的数组,消息来源电话,消息编号
//|				
//|返回:解析成功则返回0x00,出错则返回相应的出错编码
//| 
//| Example:    
//|             char Phone[15];
//|             int  Record;
//|             int  Data[100];
//|             char Str[]="+CMGL: 14,\"REC UNREAD\",\"8613575588314\",,\"04/05/29,21:07:08+00\"\xD\xAX010101032012345678FF002613666673107    13800571500    011234005600000014F6X\xD\xAOK";
//|             PareString(Str,Data,Phone,&Record);            
/////////////////////////////////////////////////////////////////////////

unsigned char ParseString(unsigned char *Str,unsigned int *Data,unsigned char* Phone,unsigned int *Record){
	
	int pos,len,i;
	unsigned int RcvCrc,CalCrc=0;
	
 	Str=strstr(Str,"+CMGL:");//搜索消息字符串的起始标志位+CMGL
	if(Str==NULL){
 		Data=NULL;
 		Phone=NULL;
 		*Record=0; 
  		return 0x07;
	}
	
	Str=Str+7; 
	pos=strpos(Str,',');      
	*Record=atoi(left(Str,pos));//接受到的消息编号

	Str=(Str+pos+1);
	pos=strpos(Str,',');
	Str=(Str+pos+2);
	pos=strpos(Str,',');
	strcpy(Phone,left(Str,pos-1)); //消息来源电话号码 

	Str=strstr(Str,"\r\n");//搜索消息数据起始位
	if(Str==NULL){
 		Data=NULL;
 		Phone=NULL;												   	
// 		*Record=0; 
  		return 0x08;
	}

	Str=Str+2;
	pos=strpos(Str,'X'); //搜索消息命令起始位
	if(pos==-1){
 		Str=NULL;
 		Data=NULL;
 		Phone=NULL;
// 		*Record=0; 
  		return 0x0a;
	}
	
	Str=(Str+pos+1);
	pos=strpos(Str,'X'); //搜索消息命令结束位
	if(pos==-1){
 		Str=NULL;
 		Data=NULL;
 		Phone=NULL;
// 		*Record=0; 
 		return 0x0b;
	}

	//对命令单元和检验单元字符串进行二进制合并,若是31命令则对电话号码不做合并

	if(Str[8]=='3'&&Str[9]=='1'){
		BinaryFuse(Str,0,24,Data,0);
		len=Data[0];
		Data[0]+=30;
		for(i=0;i<30;i++)
			Data[len+1+i]=Str[24+i];
		BinaryFuse(Str,54,pos-54,Data,Data[0]);
	}
	else
  		BinaryFuse(Str,0,pos,Data,0);

    //CRC 校验
	RcvCrc=Data[(Data[0])]*256+Data[(Data[0])-1];
	for(i=1;i<=Data[0]-2;i++)
		CalCrc=cal_crc(Data[i],CalCrc);
	if(RcvCrc!=CalCrc){
		Str=NULL;
 		return 0x05;
	}
	Data[0]-=2;

	//命令体长度检验
	if(Data[12]!=Data[0]-12){
		Str=NULL;
 		Data=NULL;
 		Phone=NULL;
 		*Record=0;
		return 0x0c;
	}
	
	Str=(Str+2);//消息命令体处理完毕
	Str=NULL;
	return 0x00;
}


/////////////////////////////////////////////////////////////////
//| Function:	GetSetValue()
//|从调试串口接收到的字符串中,解析出有效数据
//| 
//|输入:源字符串,目的数组,命令号
//|
//|返回:解析成功则返回0x00,出错则返回相应的出错编码                  
//| 
//| Example:    
//|             char result;
//|				unsigned int kind;
//|             unsigned char  Data[100];
//|             char Str[]="set 1=1234";
//|             result=GetSetValue(Str,Data,&kind);
/////////////////////////////////////////////////////////////////////////
char GetSetValue(unsigned char* Str,unsigned int* Data,unsigned int* kind)
{
	int pos,i;

	Str=strstr(Str,"set");
	if (Str==NULL)
		return -1;

	Str=Str+3;
	pos=strpos(Str,'=');
	if (pos==-1)
		return -2;
	*kind=atoi(left(Str,pos));
	Str=Str+pos+1;
	pos=strpos(Str,'\r');
	if ((pos==-1)||(pos>32))
		return -3;
	if ((*kind==1)||(*kind==2))	//电话号码
	{
		Data[0]=pos;
		for (i=1;i<=pos;i++)
			Data[i]=Str[i-1];
	}
	else
	{
  		BinaryFuse(Str,0,pos,Data,0);
	}
	return 0;
}

/////////////////////////////////////////////////////////////////
//| Function:	GetEEPROMValue()
//|从调试串口接收EEPROM内容读取命令
//| 
//|输入:源字符串,目的数组,命令号
//|
//|返回:解析成功则返回0x00,出错则返回相应的出错编码                  
//| 
//| Example:    
//|             char result;
//|				unsigned int *start,*length;
//|             char Str[]="get 1,5";
//|             result=GetEEPROMValue(Str,&start,&length);
/////////////////////////////////////////////////////////////////////////
char GetEEPROMValue(unsigned char* Str,unsigned int* start,unsigned int* length)
{
	int pos;

	Str=strstr(Str,"get");
	if (Str==NULL)
		return -1;

	Str=Str+3;
	pos=strpos(Str,',');
	if (pos==-1)
		return -2;
	*start=atoi(left(Str,pos));
	Str=Str+pos+1;
	pos=strpos(Str,'\r');
	if ((pos==-1)||(pos>32))
		return -3;
	*length=atoi(left(Str,pos));
	return 0;
}

/////////////////////////////////////////////////////////////////
//| Function:	BinaryDivide()
//|将源整数数组进行如下处理,从数组的第二位起逐个将整数转换成ASCII码				
//| 
//|输入:源整数数组,起始位置,拆分的长度,目的字符串			
//|
//|返回:void                  
//| 
//|Example:    
//|             int  data[3]={0x02,0x12,0x34};
//|             char str[4];             
//|             BinaryDivide(data,1,2,str,0); //str[]="1234"           
///////////////////////////////////////////////////////////

void BinaryDivide(unsigned int* Data,int DStart, int Len,unsigned char* Str){
	int i;
	char buffer[3];
	
	if(DStart<=0)
		DStart=1;
	
	if(Len<=0)
		Len=1;
	if(Len>Data[0])
		Len=Data[0];

	for(i=0;i<Len;i++){
		sprintf(buffer,"%2X",Data[DStart+i]);
 		if(buffer[0]==' ')
    		buffer[0]='0';
		Str[2*i]=buffer[0];
		Str[2*i+1]=buffer[1];
// 		strcat(Str,buffer);
	}
	Str[2*i]='\0';
}

/////////////////////////////////////////////////////////
//| Function:	BuildCmd()
//|功能: 根据命令单元生成校验单元,然后进行二字节拆分,然后添加结束标志生成最终命令包	
//|				
//|输入: 源整数数组命令单元,字符串格式的命令包
//|				
//|输出: void                
//|
//| Example:    
//|             int  Data[100]={0x11,0x01,0x01,0x01,0x03,0x30,0x12,0x34,0x56,0x78,0x01,0x00,0x05,0x12,0x34,0x56,0x78,0x01};;
//|             char Cmd[100];
//|             BuildCmd(Data,Cmd); //Cmd="010101033012345678010005123456780144F7"  +X  +26数字        
////////////////////////////////////////////////////
void BuildCmd(unsigned int* Data,unsigned char * Cmd){
	int i,len;
	unsigned int CalCrc=0;
//    char flag[3];
	
	CalCrc=0;	//modified
	for(i=1;i<=Data[0];i++)
		CalCrc=cal_crc(Data[i],CalCrc);
	
	Data[Data[0]+1]=CalCrc%256;
	Data[Data[0]+2]=CalCrc/256;
	Data[0]+=2;

//	if(Data[5]==0x20||Data[5]==0x31){
	if((Data[5]==0x20)&&(Data[0]>15))	//鉴权正确的20命令,去处鉴权错误20命令的干扰
	{
  		BinaryDivide(Data,1,12,Cmd);
  		for(i=0;i<30;i++)
  			Cmd[24+i]=Data[13+i];
  		BinaryDivide(Data,43,Data[0]-42,Cmd+54);
		len=74;		
	}
	else
	{
  		BinaryDivide(Data,1,Data[0],Cmd);
		len=Data[0]*2;
	}

	Cmd[len]='X';
	Cmd[len+1]=26;
	Cmd[len+2]='\0';
}

/////////////////////////////////////////////////////////////////////////
//| Function:	unsigned char ParseCellInfo()
//|从源字符串中获取网络小区的基本参数
//|					
//|输入:源字符串,小区号,Bcch,Bsic,Rxlev
//|				
//|返回:解析成功则返回0x00,出错则返回相应的出错编码
//| 
//| Example:    
//|             char Phone[15];
//|             unsigned int  Bcch;
//|				unsigned char Bsic,Rxlev;
//|             char Str[]="+MCELL: 1 BC 0085 02-082B<LF>460000 10471 33<LF>018 018 *** ***<LF>0 A1aI 22298 20<LF>8 *** 7 1 20 14<LF>-100 GPI1 ****\rOK";
//|             ParseCellInfo(Str,CellNo,&Bcch,&Bsic,&Rxlev);            
/////////////////////////////////////////////////////////////////////////
unsigned char ParseCellInfo(unsigned char *Str,unsigned char CellNo,unsigned int *Bcch,unsigned char* Bsic,unsigned char *Rxlev,unsigned int *CellId){
	
	unsigned int i;
	unsigned char screen[5];
	
 	Str=strstr(Str,"+MCELL:");//搜索消息字符串的起始标志位+MCELL
	if(Str==NULL){
		*Bcch=0;
		*Bsic=0;
		*Rxlev=0;
  		return 0x1;
	}
	if (CellNo==0)
	{
		Str=Str+7;
		Str=Str+6;
		*Bcch=atoi(left(Str,4));	//Bcch:6~9
		Str=Str+5;
		*Bsic=atoi(left(Str,2));	//Bsic:11~12
		Str=Str+3;
		*Rxlev=atoi(left(Str,3));	//Rxlev:13~16
		Str=Str+12;
		*CellId=atoi(left(Str,5));
		return 0;
	}
	else
	{
		i=CellNo;
		sprintf(screen,"N%u",i);

	 	Str=strstr(Str,screen);//搜索相邻小区信息起始标志"N*"
		if(Str==NULL){
			*Bcch=0;
			*Bsic=0;
			*Rxlev=0;
	  		return 0x2;
		}
		Str=Str+3;
		*Bcch=atoi(left(Str,4));	
		Str=Str+5;
		*Bsic=atoi(left(Str,2));	
		Str=Str+3;
		*Rxlev=atoi(left(Str,3));
		*CellId=0;
		return 0;
	}
}


unsigned char  gsmInvertNumbers(const char *pSrc, char *pDst, unsigned char nSrcLength)
{
    unsigned char  nDstLength;   // 目标字符串长度
    char ch;          // 用于保存一个字符
    unsigned char  i;
    
    // 复制串长度
    nDstLength = nSrcLength;
    
    // 两两颠倒
    for(i=0; i<nSrcLength;i+=2)
    {
        ch = *pSrc++;        // 保存先出现的字符
        *pDst++ = *pSrc++;   // 复制后出现的字符
        *pDst++ = ch;        // 复制先出现的字符
    }
    
    // 源串长度是奇数吗?
    if(nSrcLength & 1)
    {
        *(pDst-2) = 'F';     // 补'F'
        nDstLength++;        // 目标串长度加1
    }
    
    // 输出字符串加个结束符
    *pDst = '\0';
    
    // 返回目标字符串长度
    return nDstLength;

}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -