Pantech.AI

How to Interface SIM900A GSM with 8051 microcontroller

GSM SIM900

Global System for Mobile Communication (GSM) is a digital cellular network standard widely used for mobile devices and long-distance communication.

Several GSM modules are available on the market, including the SIM900, SIM700, SIM800, SIM808, and SIM5320.

The SIM900A module supports data transfer over GPRS, SMS sending and receiving, and voice calls. It communicates serially with devices like microcontrollers or PCs using AT commands.

To connect the SIM900A module to a cellular network, a SIM card from a network operator is required.

For more details on using the SIM900A, refer to the SIM900A GSM/GPRS Module section in sensors and modules.

The GSM/GPRS module communicates with a microcontroller or PC terminal via USART.

For information on using UART with the 8051 microcontroller, refer to the UART in 8051 topic in the 8051 Inside section.

GSM SIM900 Connection with 8051

GSM SIM900 Connection with 8051

Application

Let’s create a simple application that automatically responds to an incoming SMS. When the user receives an SMS with the message “call me,” the system will automatically initiate a call back to the sender of the message.


/*
    SIM900 GSM Interfacing with 8051
    http://www.electronicwings.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;
	}
}

Leave a Comment

Your email address will not be published. Required fields are marked *