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

📄 main.c

📁 单片机通过控制SIM300C 短信模块读GPS 数据
💻 C
📖 第 1 页 / 共 2 页
字号:
/* IO 口模拟232通讯程序
使用两种方式的C程序 占用定时器0
**********************************************/
#include <ctype.h>
#include <reg51.h>
#include <stdio.h>
#include <string.h>
#define DEBUG_SMS

#define byte unsigned char
extern void sector_erase(unsigned short int dataAddr);
extern void byte_program(unsigned short int dataAddr, unsigned char dataByte);
extern unsigned char byte_verify(unsigned short int dataAddr);
extern bit sendSMS(byte *telnum, byte  *STRING);
extern bit getAck(byte Len,byte *getData);
extern void deleSMS(byte *POINT);
byte gsmDecode7bit(unsigned char* pSrc, char* pDst, byte nSrcLength);
pdata byte pData[256];
sbit BT_SND =P1^7;
sbit BT_REC =P1^6;

//sbit BT_SND =P3^1;
//sbit BT_REC =P3^0;
//sbit LED_RED =P1^1;



typedef struct{		
		byte Index[4];		//短消息索引
		byte TelNum[16];
		byte Ref[20];
		byte SMS_text[100];
	
	}SMS_INFO;
	



byte	RxFlag=0;							
byte	RecTimeOut=0;	
byte	RecStatus=0;	
byte	RxCount=0;		
bit		SMS_TYPE;
// 设置接收短信的手机号
//6
//code	byte Owner[]="Owner";

// 更改密码
//code	byte Password[]="Password";

//取信息
//code	byte GetMessage[]="Get Message";

code 	byte ACK_OK[]={'O','K',0X0D,0X0A,0X00};
//code    byte CharZ[]={'>',0X00};
//code    byte CMG[]={'+','C','M','G',0};

bit 	LongDataFlag;

#ifdef DEBUG_SMS
extern void putch(byte ch);
#endif

#define F_TM F0

#define TIMER0_ENABLE  TL0=TH0; TR0=1;
#define TIMER0_DISABLE TR0=0;

sbit ACC0=   ACC^0;
sbit ACC1=   ACC^1;
sbit ACC2=   ACC^2;
sbit ACC3=   ACC^3;
sbit ACC4=   ACC^4;
sbit ACC5=   ACC^5;
sbit ACC6=   ACC^6;
sbit ACC7=   ACC^7;


// 在 S 串中找 串 T ,算法如下。 从第一个数开始比较之前,先求出各串的长度。
// 当比较的字符数都小于各自的串长度时,进行比较 当取出的数据比较相等时,设量i,j 都加 1.
// 不相等时, i=i-j+2,j=1;
// 退出比较,当j> t 串的长度时,比较成功。即在 i- t 长处发现相待。

unsigned char cmp(unsigned char *array1,unsigned char *array2) 
  {
    unsigned char i;    
   
    unsigned char m=strlen (array2); 

	for(i=0;i<256-m;i++)
	{
	if(memcmp(&array1[i],array2,m)==0) 
		return(i);
	}
	return(0xff);


   }


//用IO模拟串口收,发数据占用定时器0
void IntTimer0() interrupt 1
{
  F_TM=1;
}

//模拟串口,发送一个字符
void PSendChar(unsigned char inch)
{			   	
	ACC=inch;	
	F_TM=0;
	BT_SND=0; 			//start bit
	TIMER0_ENABLE; 		//启动
	while(!F_TM);
	
	BT_SND=ACC0; 		//先送出低位
	F_TM=0;
	while(!F_TM);
	
	BT_SND=ACC1;
	F_TM=0;
	while(!F_TM);
	
	BT_SND=ACC2;
	F_TM=0;
	while(!F_TM);
	
	BT_SND=ACC3;
	F_TM=0;
	while(!F_TM);
	
	BT_SND=ACC4;
	F_TM=0;
	while(!F_TM);
	
	BT_SND=ACC5;
	F_TM=0;
	while(!F_TM);
	
	BT_SND=ACC6;
	F_TM=0;
	while(!F_TM);
	
	BT_SND=ACC7;
	F_TM=0;
	while(!F_TM);
	
	BT_SND=1;
	F_TM=0;
	while(!F_TM);
	F_TM=0;
	
	TIMER0_DISABLE; 	//停止timer
}

//模拟串口,接收一个字符
unsigned char PGetChar()
{								
	TIMER0_ENABLE;
	F_TM=0;
	while(!F_TM); //等过起始位
	ACC0=BT_REC;
	
	TL0=TH0;
	
	F_TM=0;
	while(!F_TM);
	ACC1=BT_REC;
	
	F_TM=0;
	while(!F_TM);
	ACC2=BT_REC;
	
	F_TM=0;
	while(!F_TM);
	ACC3=BT_REC;
	
	F_TM=0;
	while(!F_TM);
	ACC4=BT_REC;
	
	F_TM=0;
	while(!F_TM);
	ACC5=BT_REC;
	
	F_TM=0;
	while(!F_TM);
	ACC6=BT_REC;
	
	F_TM=0;
	while(!F_TM);
	ACC7=BT_REC;
	
	F_TM=0;
	
	while(!F_TM)
	{
		if(BT_REC)
		{
		break;
		}
	}
	TIMER0_DISABLE; //停止timer
	return ACC;

}


//发送字符串
unsigned char send_str(unsigned char *str)
{
 unsigned char i;
  i=0;
 	while( str[i] != 0 ){
   	PSendChar(str[i]); 
	i++;	
	}
 
  return(0);
 }
 

unsigned char SendAT(unsigned char *command,unsigned char * Cmp_Data,unsigned char *ACK)
{
  unsigned char i=0;
  unsigned char ACK_LEN;  
  unsigned long m;
   
  if(strlen(command) > 0)
  { 	
    	while(1)
	  	{		
        
		if(command[i] == 0 || command[i] == '\n' || command[i] == '\r' )
	       {
			PSendChar(0x0D);
			break;
			}

		else
			{
			PSendChar(command[i]);
			
			}
	
		i++;
		}
	}

	ACK_LEN = strlen(Cmp_Data);
	    
/*
	三秒钟内无回复,认为超时退出.
*/
	m = 500000L;
	i = 0;
	while(m--)
	{
	
	  if(BT_REC==0)
	  {
	  	
	  	ACK[i] =PGetChar();	
		m = 200000L;
		if(i<0xff)
		i+=1;
		if(i>=ACK_LEN)
			{ 
				if(memcmp(&ACK[i-ACK_LEN],Cmp_Data,ACK_LEN)==0)
				{
				 if(i>=0x80) LongDataFlag = 1;			//收到的数据确实很长	
				 return(i+0x80);
				}	
			
			}		 	
	 	}	 
	
	}

 return(i);	  //回复收到的数据长度.

}


unsigned long delay;

void Delay100mS(byte Cnt)
{
 unsigned int m_100MS;	  
 m_100MS = 0;
 while(--Cnt)
 {
   for(m_100MS=0;m_100MS<60000;m_100MS++);
 }

}

bit CPL;
void main()
{
	byte i,j,cc,Len;
	byte Pt;					//分析信息指针

	SMS_INFO pdata *Info = &pData[0];	
	

	SCON= 0X50;				//定议串口
	TMOD=0x22; 				/*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */
	PCON=0X80;				//波特率加倍
								 	
	TR0=0; 
	TF0=0;
	TH0 =256-80;			//用IO模拟的串口速率为 19200.
	TL0=TH0;
	ET0=1;					//允许定时器0中断

   	TH1 = 0XF6;			 	//单片机的串口速度为9600,用于接收GPS数据.
	TL1 = 0XF6;					  
	TR1 = 1;				//启动定时器1
	ES = 1;					//允许串口中断

	EA=1;	  				//开总中断
  	delay = 0;

	sector_erase(0x2800);

	while(1)
	{

	#ifdef 	DEBUG_SMS 
		putch('A');	
	#endif	 
 		memset(pData,0,256);
		Len =SendAT("ATE0",ACK_OK,pData+150);
		if(Len>=0X80) break;					//开机是如果未接上SMS模块,则一直等待	 
			
	}

// EEPROM用4扇区可用.  
/*
0--14 为密码
15--39 为手机号.
40--59为 管理者名字

60为 BCC
61,62为 55,66

*/
	cc = 0;
	for(i=0;i<60;i++)
	cc +=byte_verify(0x2E00+i);

	if(byte_verify(0x2E00+60)!=cc ||byte_verify(0x2E00+61)!=0x55 || byte_verify(0x2E00+62)!=0x66)
	{		 
		putch('B');	
		sector_erase(0x2E00);					//把旧数据擦除
		memset(&pData[0],0xff,100);
		for(i=0;i<6;i++)
		pData[i]='8';						//默认密码为 888888
		pData[6]=0;
		memcpy(pData+15,"0D91683156909013F4",19);

		memcpy(pData+40,"Hello",6);
		Len = 0;
		for(i=0;i<60;i++)
		Len +=pData[i];
		pData[60] =Len;
		pData[61] =0x55;
		pData[62] =0x66;
		for(i=0;i<63;i++)
		byte_program((0x2E00+i),pData[i]);
	}

	else
	{
		for(i=0;i<63;i++)
		{
		pData[i] =byte_verify(0x2E00 +i);
		putch(pData[i]);
		}
	
	}


	sendSMS(pData+15,"How Are You Owner !");		//开机时发一条短信报告.

	REN = 1;
	while(1)
	{   
		REN = 1;
		delay++;
		if(delay>=600000L)		   //读短信
		{
			REN = 0;
		    Len=0;
			LongDataFlag = 0;
			memset(pData,0,256);
			Len =SendAT("ATE0",ACK_OK,pData);			
			if(cmp(pData,"OK")==0XFF)				
				goto	NoMobil;


 
		putch('O');
		putch('K');
		putch(0x0d);
		putch(0x0a);


			LongDataFlag =0;
			memset(pData,0,256);

			SendAT("AT+CMGL=0",ACK_OK,pData);	
/*			
			if(CPL)
			{
			CPL=0;
			SendAT("AT+CMGR=6",ACK_OK,pData);	//密码 888888 设置手机为 13650909314
			}
			else
			{
			CPL =1;
			SendAT("AT+CMGR=7",ACK_OK,pData);	//旧密码 888888 更改密码为456ABCJIE				
			}
*/			
			Pt =cmp(pData,"+CMG");
			if(Pt==0xff)	goto NoMobil;
			{		  			 
			for(i=0;i<256;i++)
			{
				if(pData[i]==0) break;
				putch(pData[i]);
			}

	putch('N');
	putch('e');
	putch('w');
	putch('S');
	putch('M');
	putch('S');
	putch(0x0d);
	putch(0x0a);		 
	
//短消息的第9个字节开始为 消息索引
			Info->Index[0] = 0;
			Info->Index[1] = 0;
			Info->Index[2] = 0;
			Info->Index[3] = 0;		
		
			if(pData[Pt+7]!=0x2C)
			{
			 Info->Index[0] = pData[Pt+7];
			 	if(pData[Pt+8]!=0x2C)
				{
			 	Info->Index[1] = pData[Pt+8];
					if(pData[Pt+9]!=0x2C)
					{
			 		Info->Index[2] = pData[Pt+9];
					} 

				} 
			} 


  
	putch('I');
	putch('n');
	putch('d');
	putch('e');
	putch('x');
	putch(0x0d);
	putch(0x0a);
		for(i=0;i<4;i++)
		{
			if(Info->Index[i]!=0)
			putch(Info->Index[i]);
		}
		
	

			for(Pt=9;Pt<25;Pt++)
			{			
			  if(pData[Pt]==0x0A)			//换行,信息开始.
			  	break;
			}
			if(Pt==25)	 		 
			{
					putch('S');
					putch('M');
					putch('S');
					putch('e');
					putch('r');
					putch('r');
					putch('o');
					putch('r');
					putch(0x0d);
					putch(0x0a);
								goto	NoMobil;
			}
//

//判断短信中心的数据长度.
			Pt +=1;
			Len =pData[Pt]<=0x39 ? pData[Pt]-0x30:pData[Pt]-0x41+10;
			Len =(Len<<4) + (pData[Pt+1]<=0x39 ? pData[Pt+1]-0x30:pData[Pt+1]-0x41+10);
			Len +=2;		
			Len =Len <<1;		//乘以2,为字节总数.
			Pt +=Len;			//Pt指向目的手机的开始地址.	

//判断目的手机的号码数		
			Len =pData[Pt]<=0x39 ? pData[Pt]-0x30:pData[Pt]-0x41+10;
			Len =(Len<<4) + (pData[Pt+1]<=0x39 ? pData[Pt+1]-0x30:pData[Pt+1]-0x41+10);
//如果码号数为奇数,要加1成为偶数.			
			i = Len;
			if(i&0x01) Len +=1;			
	putch('t');
	putch('e');
	putch('l');
	putch(0x0d);
	putch(0x0a);
//把目的手机号保存下来.

			for(i=Pt;i<Pt+Len+4;i++)
			{
				Info->TelNum[i-Pt] =pData[i];						  
			}

			Info->TelNum[i-Pt] =0;			//手机号结束符

 //指针指向手机号码后的第一个字节.
			Pt = i;
			for(i=0;i<Len+4;i++)	
			putch(Info->TelNum[i]);	

			if(pData[Pt+2]=='0' && pData[Pt+3]=='0')	//是ASC码短信.7-bit编码
			{				
			    SMS_TYPE=0;
			}

			else if(pData[Pt+2]=='0' && pData[Pt+3]=='8')
			{
				SMS_TYPE=1;			
			}

			else		//只处理PDU格式和ASC码格式.其它不处理
					goto	InfoEnd;
			

			Pt +=18;				//短信息数据长度字节.

//		   	putch(pData[Pt]);		//转换成ASC码后的字符.
//			putch(pData[Pt+1]);		//短信字符数

			Len =pData[Pt]<=0x39 ? pData[Pt]-0x30:pData[Pt]-0x41+10;
			Len =(Len<<4) + (pData[Pt+1]<=0x39 ? pData[Pt+1]-0x30:pData[Pt+1]-0x41+10);
		   	Len = Len<<1;		  	//乘以2,为信息字节总数.
		    Pt+=2;					//指向信息开始地址.
		
		
	putch('I');
	putch('n');
	putch('f');
	putch('o');

		if(SMS_TYPE==0)				//ASC码,要用7-BIT解码解出内容
		{
			i = Pt;
			j = Pt;
			while(1)
			{
			if(pData[i]==0x0D || pData[i]==0x0A) break;
			cc =pData[i]<=0x39 ? pData[i]-0x30:pData[i]-0x41+10;
			cc =(cc<<4) + (pData[i+1]<=0x39 ? pData[i+1]-0x30:pData[i+1]-0x41+10);
			pData[j]=cc;
			i +=2;
			j +=1;		
			}
		
			Len =gsmDecode7bit(&pData[Pt],&Info->SMS_text[0],j-Pt);
			Info->SMS_text[Len] = 0;
			putch('A');
		}
		else		//PDU码,解出内容
		{				
			j = 0;
			for(i=0;i<Len;)		
			{
			    i+=2;
				cc =pData[Pt+i]<=0x39 ? pData[Pt+i]-0x30:pData[Pt+i]-0x41+10;			
				i+=1;		
				cc =(cc<<4) + (pData[Pt+i]<=0x39 ? pData[Pt+i]-0x30:pData[Pt+i]-0x41+10);
				Info->SMS_text[j] = cc;
				i+=1;
				j+=1;
			}
			Info->SMS_text[j] =0;		
			Len = j;
			putch('P');
		}

		putch(0x0d);
		putch(0x0a);

		putch('T');
		putch('E');
		putch('X');
		putch('T');
		putch(':');
		putch(' ');


⌨️ 快捷键说明

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