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

📄 gprs_modem.c

📁 是一套AT 命令
💻 C
字号:
/*
*Copyright (c) 2006 .南京e嵌嵌入式科技有限公司
*All rights reserved
*
*filename :gprs_modem_test.c
*
*version 1.0
*
*author:lichao 
*completed:20070723
*
*description:The file is used to test whether the gprs modem works correctly
*
*email:lichao@njupt.edu.cn
 */


//int fd;
#include "gprs_modem.h"
int speed_arr[] = { B38400, B57600,B19200, B9600, B4800, B2400, B1200, B300 };
int name_arr[] = {38400, 57600, 19200,  9600,  4800,  2400,  1200,  300  };
//char *DEV="/dev/ttyS0";
void set_speed(int fd, int speed)
{
  int   i;
  int   status;
  struct termios   Opt;
  tcgetattr(fd, &Opt);
  for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
   {
   	if  (speed == name_arr[i])
   	{
   		tcflush(fd, TCIOFLUSH);
    		cfsetispeed(&Opt, speed_arr[i]);
    		cfsetospeed(&Opt, speed_arr[i]);
    		status = tcsetattr(fd, TCSANOW, &Opt);
    		if  (status != 0)
            		perror("tcsetattr fd1");
     		return;
     	}
   	tcflush(fd,TCIOFLUSH);
   }
}
/**
*@brief   设置串口数据位,停止位和效验位
*@param  fd     类型  int  打开的串口文件句柄*
*@param  databits 类型  int 数据位   取值 为 7 或者8*
*@param  stopbits 类型  int 停止位   取值为 1 或者2*
*@param  parity  类型  int  效验类型 取值为N,E,O,,S
*/
int set_parity(int fd,int databits,int stopbits,int parity)
{
 struct termios options;
 if  ( tcgetattr( fd,&options)  !=  0)
  {
  	perror("SetupSerial 1");
  	return(FALSE);
  }
  options.c_cflag &= ~CSIZE;/*屏蔽字符大小位*/
  switch (databits) /*设置数据位数*/
  {
  	case 5:
  		options.c_cflag |= CS5;//选择5位数据位
  		break;
  	case 6:
  		options.c_cflag |= CS6;//选择6位数据位
  		break;
  	case 7:
  		options.c_cflag |= CS7;//选择7位数据位
  		break;
  	case 8:
		options.c_cflag |= CS8;//选择8位数据位
		break;
	default:
		fprintf(stderr,"Unsupported data size\n");
		return (FALSE);
	}
  switch (parity)
  	{
  	case 'n':
	case 'N':
		options.c_cflag &= ~PARENB;   /* Clear parity enable */
		options.c_iflag &= ~INPCK;     /* Enable parity checking */
		break;
	case 'o':
	case 'O':
		options.c_cflag |= (PARODD | PARENB);  /* 设置为奇效验*/ 
		options.c_iflag |= INPCK;             /* Disnable parity checking */
		break;
	case 'e':
	case 'E':
		options.c_cflag |= PARENB;     /* Enable parity */
		options.c_cflag &= ~PARODD;   /* 转换为偶效验*/  
		options.c_iflag |= INPCK;       /* Disnable parity checking */
		break;
	case 'S':
	case 's':  /*as no parity,无校验位*/
		options.c_cflag &= ~PARENB;
		options.c_cflag &= ~CSTOPB;
		break;
	default:
		fprintf(stderr,"Unsupported parity\n");
		return (FALSE);
		}
  	/* 设置停止位*/   
  	switch (stopbits)
  	{
  	case 1:
  		options.c_cflag &= ~CSTOPB;
		break;
	case 2:
		options.c_cflag |= CSTOPB;
		break;
	default:
		fprintf(stderr,"Unsupported stop bits\n");
		return (FALSE);
	}
  	/* Set input parity option */
  	if (parity != 'n')
  		options.c_iflag |= INPCK;
    	
    	/*如果不是开发终端之类的,只是串口传输数据,而不需要串口来处理,
	那么使用原始模式(Raw Mode)方式来通讯,设置方式如下*/
	options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
	options.c_oflag  &= ~OPOST;   /*Output*/
	
	options.c_iflag &= ~(IXON | IXOFF | IXANY);
		
    	options.c_cc[VTIME] = 10; // 1 seconds
    	options.c_cc[VMIN] = 0;

  	tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
  	if (tcsetattr(fd,TCSANOW,&options) != 0)
  	{
  		perror("SetupSerial 3");
		return (FALSE);
	}
  	return (TRUE);
}

/**
*设置流控
*/
void SetFlowControl(int com,int mode)
{
	struct termios options;
 	if  ( tcgetattr( com,&options)  !=  0)
  	{
  		perror("SetupSerial 1");
  		return;
  	}
  	switch(mode)
  	{
  		case 1:
  			options.c_cflag &= ~CRTSCTS;//无流控
			break;
		case 2:
			options.c_cflag |= CRTSCTS;//硬件流控
			break;
		case 3:
			options.c_cflag |= IXON|IXOFF|IXANY;//软件流控
	}
	tcsetattr(com,TCSANOW,&options);
	
		
}

/**
*@breif 打开串口,
*参数Dev为打开设备的设备名,如/dev/ttyS0
*返回值:-1:打开失败,否则返回打开设备的设备句柄
*/
int Open_Init_COM(char *Dev)
{
	int	com=open( Dev, O_RDWR | O_NOCTTY);         //| O_NOCTTY | O_NDELAY
	if (-1 == com)
	{ 
		/*设置数据位数*/
		perror("Can't Open Serial Port");
		return -1;
	}
	/*初始化串口*/
	//设置串口属性
	fcntl(com,F_SETFL,0);//没有数据就阻塞,直到数据到来或者到了规定时间。
	//如果要使read()函数立即返回,请用fcntl(com,F_SETFL,FNDELAY)函数
	set_speed(com,57600);//速度9600BPS
	set_parity(com,8,1,'s');//数据位8位,1位停止位,没有奇偶校验位
	SetFlowControl(com,1);	//无流控
	return com;
}


/**
*从串口读取数据
*/
int ReadCOM(int n,char *buf,int length)
{
	return read(n,buf,length);
}
/**
*向串口写数据
*/
int WriteCOM(int n,char *buf,int length)
{
	return write(n,buf,length);
}
/**
*关闭串口
*/
int CloseCOM(int n)
{
	return close(n);
}

/*
   *接收短消息前的准备
*/
int Gprs_MessageReady(int com)
{   
	  int nRead,k=0,num=0;
	  char gprs_buf[100];
	  char *at_cmd;
          char ReceiveMessageCmd[][30]={{"ATZ\r"},{"AT+CMGF=1\r"},{"AT+CSCA=\"+8613800250500\"\r"},{""}};
	  at_cmd=ReceiveMessageCmd[k++];
	  while(strcmp(at_cmd,"")) {
	  	 bzero(gprs_buf,100);
	  	 WriteCOM(com,at_cmd,strlen(at_cmd));
	  	 sleep(2);
	  	 at_cmd=ReceiveMessageCmd[k++];
	  	 if((nRead=ReadCOM(com,gprs_buf,100))<0) {
	  	 	   perror("ReadCOM error");
	  	 	   return -1;
	  	 }
	  	 printf("num=%d gprs_buf=%s",num,gprs_buf);
	  	 if(strstr(gprs_buf,"OK")!=NULL) {
	  	 	  num++;
	  	 	  continue;
	  	 }else 
	  	 {
	  	 	 return num;
	  	 } 
	  }
	  return 0; 	 
	     
}
/*
 解析短信内容,这是移动的解析方式,联通可能不同
*/
int Gprs_AnalyzeMessage(char *as_gprs_info,struct shortmsg *pShortMsg) {
 char *pGprs_sender,*pGprs_time,*pGprs_con,*pGprs_con_last;
 char Gprs_recvcon[100];
 int i=0,j=0;
     memset(pShortMsg->sender,0,20);
     memset(pShortMsg->msgcontent,0,100); 
     if((pGprs_sender=strstr(as_gprs_info,"+86"))==NULL) return 1;                  
         strncpy(pShortMsg->sender,pGprs_sender,14);
         printf("sender %s\n",pShortMsg->sender);
     if((pGprs_time=strstr(pGprs_sender,"\",,\""))==NULL) return 2;
         /* pShortMsg->sendtime=time(NULL);
          printf("sendtime %s",pShortMsg->sendtime);*/
     if((pGprs_con=strstr(pGprs_sender,"\n\n"))==NULL) return 3;
         pGprs_con+=2;
     while(isalnum(pGprs_con[i]))
     {
        Gprs_recvcon[j]=pGprs_con[i];
        i++;j++;
     }
     strcpy(pShortMsg->msgcontent,Gprs_recvcon);
         printf("msgcontent %s\n",pShortMsg->msgcontent);
     return 0;  
	
}
/* 
  *写入短信中的Index号码
*/
void Gprs_GetMessage(int com)
{  
  int nRead,nWrite;
  char gprs_rev_Number[25];
  char getNumber[10],*catNumber;
  char  get_message[25];
  char  message_info[][15]={{"AT+CMGR="},{"AT+CMGD="}};
  int  k=0,i=0;    
    catNumber=getNumber;
    
   memset(gprs_rev_Number,0,25);
   while(strlen(gprs_rev_Number)<7) {
   	    nRead=ReadCOM(com,gprs_rev_Number,25);//读取+CMTI:“SM”,56   
   }    
   printf("gprs_rev_Number=%s\n",gprs_rev_Number);
   memset(getNumber,0,10);   
    for(i=0;i<nRead;i++) 
    {
    	 if(gprs_rev_Number[i]>='0'&&gprs_rev_Number[i]<='9') 
         {
            getNumber[k]=gprs_rev_Number[i];
            k++;
         }//取得INDEX号码
    }
    
    memset(gprs_rev_Number,0,25);
    nRead=ReadCOM(com,gprs_rev_Number,25);//再次读取因为有时候只能读取最后两位中的一位如56 有时只能读取5原因不明,所以只能再次读取一次
   
    if(nRead>0)
    {
      for(i=0;i<nRead;i++) {
         if(gprs_rev_Number[i]>='0'&&gprs_rev_Number[i]<='9')
         {
            getNumber[k]=gprs_rev_Number[i];
            k++;
         }
      }//取得INDEX号码
    }
    memset(get_message,0,25);     	
    getNumber[k++]='\r';       	       
    strncpy(get_message,message_info[0],strlen(message_info[0]));                             
    strncat(get_message,catNumber,k);
      WriteCOM(com,get_message,strlen(get_message));	
      sleep(2);  
    
}
/*
  *读取短信信息
*/
int Gprs_RecvRead(int com,struct shortmsg *pShortMsg) {
	 char gprs_rev_buf[100];
   int nRead;
   int i;    
   memset(gprs_rev_buf,0,100);     
	
	 
   
    if((nRead=ReadCOM(com,gprs_rev_buf,100))>0) 
    { 
        for(i=0;i<nRead;i++)
      {  
         printf("%c",gprs_rev_buf[i]);
         
      }
         printf("\n");
       Gprs_AnalyzeMessage(gprs_rev_buf,pShortMsg);
       
    }                    

}
/*
*收短信,并将短信内容解析出来
*/
int Gprs_ReceiveMessage(int com,struct shortmsg *pShortMsg)
{       
  pid_t pc,pr;
  int   ret;
  
      Gprs_GetMessage(com);
      Gprs_RecvRead(com,pShortMsg);
}



⌨️ 快捷键说明

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