0°

(十二)51进阶:SIM900A GSM与8051连接教程

介绍

全球移动通信系统(GSM)是用于移动设备的数字蜂窝系统。它是一种广泛用于长途通信的移动国际标准。 市场上有各种GSM模块,如SIM900,SIM700,SIM800,SIM808,SIM5320等。 SIM900A模块允许用户通过GPRS发送/接收数据,发送/接收短信和拨打/接听语音电话。 它使用AT命令与微控制器,PC等设备串行通信。 要将SIM900A模块与蜂窝网络连接,需要网络运营商提供的SIM卡。 GSM / GPRS模块使用USART通信与微控制器或PC终端通信。

电路连接原理图

(十二)51进阶:SIM900A GSM与8051连接教程

SIM900A GSM模块与8051连接

应用

让我们设计一个小应用程序,用户将收到短信“call me”,用户将自动呼叫该消息发送者。

/*
    SIM900 GSM Interfacing with 8051
    https://www.qutaojiao.com 
 */ 
#include<reg52.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "LCD_8_bit.h"			/* include 16x2 LCD Header file */
#include "UART_Interrupt.h"		/* include UART Header file */

void GSM_Begin();				           			
void GSM_Calling(char *);          
void GSM_HangCall();
void GSM_Response();
void GSM_Response_Display();
void GSM_Msg_Read(int);
int GSM_Wait_for_Msg();				/* check whether new msg arrival */
void GSM_Msg_Display();
void GSM_Msg_Delete(unsigned int);	/* delete msg at specific location*/
void GSM_Send_Msg(char* , char*);	/* send messages*/
void GSM_Delete_All_Msg();			/* delete all msgs */

idata char buff[50];				/* buffer to store responses and messages */
char status_flag = 0;				/* for checking any new message */
volatile int buffer_pointer;
idata char Mobile_no[14];			/* store mobile no. of received message */
idata char message_received[50];	/* save received message */
int position = 0;					/* save location of current message */

int main(void)
{
	int is_msg_arrived;
	buffer_pointer = 0;	
	memset(message_received, 0, 35);
	LCD_Init();
	UART_Init();					/* initialize UART communication */
	Ext_int_Init();
	LCD_String_xy(1,0,"GSM Initializing");
	delay(3000);
	LCD_Clear();
	LCD_String_xy(1,0,"AT");    
	GSM_Begin();					/* initialize GSM */
	LCD_Clear();	
	while (1){
		
		/*check if any new message received */
		if(status_flag == 1){					
			is_msg_arrived = GSM_Wait_for_Msg();	/*check for new message arrival*/
			if(is_msg_arrived)
			{
				LCD_Clear();
				LCD_String_xy(1,0,"new message");	/* new message arrived */
				delay(1000);
				LCD_Clear();
				GSM_Msg_Read(position);				/* read arrived message */		
				delay(3000);
					
			/*check if received message is "call me" */
				if(strstr( message_received,"call me")){
					
					GSM_Calling(Mobile_no);			/* call sender of message */
					LCD_Clear();
					LCD_String_xy(1,0,"Calling...");
					delay(20000);
					GSM_HangCall();   				/* hang call */
					LCD_String_xy(1,0,"Hang Call");
					delay(1000);
				}
	
				LCD_Clear();
				GSM_Msg_Delete(position);		/* to save SIM memory delete current message */
				LCD_String_xy(1,0,"Clear msg");
				GSM_Response();
				delay(1000);
			
			}
				
				is_msg_arrived=0;
				status_flag=0;
				LCD_Clear();	
			}
		LCD_String_xy(1,0,"waiting for msg");
		memset(Mobile_no, 0, 14);
		memset(message_received, 0, 60);
		
		
	}
}

void GSM_Begin()
{

	while(1)
	{
		LCD_Command(0xc0);
		UART_SendString("ATE0\r");	/* send ATE0 to check module is ready or not */
		delay(500);
		if(strstr(buff,"OK"))
		{
			GSM_Response();			/* get Response */
			memset(buff,0,50);
			break;
		}
		else
		{
			LCD_String("Error");
		}
	}
	delay(1000);

	LCD_Clear();
	LCD_String_xy(1,0,"Text Mode");
	LCD_Command(0xc0);
	UART_SendString("AT+CMGF=1\r");/* select message format as text */
	GSM_Response();
	delay(1000);
}

void GSM_Msg_Delete(unsigned int position)
{
	idata char delete_cmd[15];
	buffer_pointer=0;
	sprintf(delete_cmd,"AT+CMGD=%d\r",position); /* delete message at specified position */
	UART_SendString(delete_cmd);
}

void GSM_Delete_All_Msg()
{
	UART_SendString("AT+CMGDA=\"DEL ALL\"\r");	 /* delete all messages of SIM */	
}

int GSM_Wait_for_Msg()
{
	char msg_location[4];
	int i;
	delay(500);
	buffer_pointer=0;

	while(1)
	{
		if(buff[buffer_pointer]=='\r' || buff[buffer_pointer]== '\n') /*eliminate "\r \n" which is start of string */
		{
			buffer_pointer++;
		}
		else
			break;
	}
		
	if(strstr(buff,"CMTI:"))				/* "CMTI:" to check if any new message received */
	{
		while(buff[buffer_pointer]!= ',')
		{
			buffer_pointer++;
		}
		buffer_pointer++;
		
		i=0;
		while(buff[buffer_pointer]!= '\r')
		{
			msg_location[i]=buff[buffer_pointer];	/* copy location of received message where it is stored */
			buffer_pointer++;
			i++;
		}

		/* convert string of position to integer value */
		position = atoi(msg_location);
		
		memset(buff,0,strlen(buff));
		buffer_pointer=0;

		return 1;
	}
	else
	{
		return 0;
	}
}

void GSM_Send_Msg(char *num,char *sms)
{
	idata char sms_buffer[30];
	buffer_pointer=0;
	sprintf(sms_buffer,"AT+CMGS=\"%s\"\r",num);
	UART_SendString(sms_buffer);		/*send command AT+CMGS="Mobile No."\r */
	delay(200);
	while(1)
	{
		if(buff[buffer_pointer]==0x3e)	/* wait for '>' character*/
		{
			buffer_pointer = 0;
			memset(buff,0,strlen(buff));
			UART_SendString(sms);		/* send msg to given no. */
			UART_TxChar(0x1a);			/* send Ctrl+Z then only message will transmit*/
			break;
		}
		buffer_pointer++;
	}
	delay(300);
	buffer_pointer = 0;
	memset(buff,0,strlen(buff));
	memset(sms_buffer,0,strlen(sms_buffer));
}

void GSM_Calling(char *Mob_no)
{
	idata char call[20];
	sprintf(call,"ATD%s;\r",Mob_no);		
	UART_SendString(call);				/* send command ATD<Mobile_No>; for calling*/
}

void GSM_HangCall()
{
	LCD_Clear();
	UART_SendString("ATH\r");			/*send command ATH\r to hang call*/
}

void GSM_Response()
{
	int i;
	unsigned int timeout=0;
	int CRLF_Found=0;
	char CRLF_buff[2];
	int Response_Length=0;
	while(1)
	{
		if(timeout>=60000)				/*if timeout occur then return */
		return;
		Response_Length = strlen(buff);
		if(Response_Length)
		{
			delay(2);
			timeout++;
			if(Response_Length==strlen(buff))
			{
				for(i=0;i<Response_Length;i++)
				{
					memmove(CRLF_buff,CRLF_buff+1,1);
					CRLF_buff[1]=buff[i];       
					if(strncmp(CRLF_buff,"\r\n",2))
					{
						if(CRLF_Found++==2)			/* search for \r\n in string */
						{
							GSM_Response_Display();	/* display response */
							status_flag=0;
							return;
						}
					}

				}
				CRLF_Found = 0;

			}
		}
		delay(1);
		timeout++;
	}
	
}

void GSM_Response_Display()
{
	int lcd_pointer = 0;
	buffer_pointer = 0;	
	while(1)
	{
		if(buff[buffer_pointer]== '\r' || buff[buffer_pointer]== '\n')  /* search for \r\n in string */
		{
			buffer_pointer++;
		}
		else
			break;
	}
	
	LCD_Command(0xc0);
	while(buff[buffer_pointer]!='\r')			/* display response till "\r" */
	{
		LCD_Char(buff[buffer_pointer]);								
		buffer_pointer++;
		lcd_pointer++;
		if(lcd_pointer==15)						/* check for end of LCD line */
		LCD_Command(0x80);
	}
	buffer_pointer=0;
	memset(buff,0,strlen(buff));
}

void GSM_Msg_Read(int position)
{
	idata char read_cmd[12];
	sprintf(read_cmd,"AT+CMGR=%d\r",position);
	UART_SendString(read_cmd);					/* read message at specified location/position */
	GSM_Msg_Display();							/* display message */
}

void GSM_Msg_Display()
{
	int i=0;
	delay(500);
	if(!(strstr(buff,"+CMGR")))					/*check for +CMGR response */
	{
		LCD_String_xy(1,0,"No message");
	}
	else
	{
		buffer_pointer = 0;
		
		while(1)
		{
			if(buff[buffer_pointer]=='\r' || buff[buffer_pointer]== 'n')  /*wait till \r\n not over*/
			{
				buffer_pointer++;
			}
			else
			break;
		}
		
		/* search for 1st ',' to get mobile no.*/
		while(buff[buffer_pointer]!=',')
		{
			buffer_pointer++;
		}
		buffer_pointer = buffer_pointer+2;

		/* extract mobile no. of message sender */
		for(i=0;i<=12;i++)
		{
			Mobile_no[i] = buff[buffer_pointer];
			buffer_pointer++;
		}
		
		do
		{
			buffer_pointer++;
		}while(buff[buffer_pointer-1]!= '\n');
		
		LCD_Command(0xC0);
		i=0;
		/* display and save message */
		while(buff[buffer_pointer]!= '\r' && i<31)
		{
				LCD_Char(buff[buffer_pointer]);
				message_received[i]=buff[buffer_pointer];
				
				buffer_pointer++;
				i++;
				if(i==16)
					LCD_Command(0x80);	/* display on 1st line */
		}
		
		buffer_pointer = 0;
		memset(buff,0,strlen(buff));
	}
	status_flag = 0;
}

/* ISR routine to save responses/new message */

void Serial_ISR() interrupt 4
{
	if(RI){
		EA = 0;
		buff[buffer_pointer] = SBUF;	/* copy SBUF(received value) to buffer */
		buffer_pointer++;
		status_flag = 1;				/* flag for new message arrival */
		RI = 0;
		EA = 1;
	}
}

本教程完整项目工程下载:

限制以下用户组阅读此隐藏内容

请先登录

您的用户组:
「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论