Sie sind auf Seite 1von 32

Circuit diagram for Interfacing SIM300 GSM modem to AT89S52

SIM300 is an GSM modem which can be controlled through AT Commands. In this tutorial i am going
to explain how to send/receive sms, how to make/receive a call, how to send a tweet to twitter using the
SIM300 modem.
I am going to use the sim300 modem with TTL output so it can be directly connected to the
microcontroller ports.
Sim300 needs a power supply of 3.4v to 4.5v, but the microcontroller circuit has only 5v supply. I am
just using a Diode 1N4007 in series with the Vcc of the modem. So a 0.6v is dropped across the diode
and so that the modem will receive only 4.4v.
SIM300 modem used by me.

Circuit Diagram

Just connect the VCC of the modem to +5V through diode and Gnd to microcontroller ground. Then
TXD pin to Pin3.0 of the microcontroller and RXD pin to P3.1 of the Microcontroller.
Dont forget you need a minimum 2A power supply, since the GSM modem consume more power at the
time of sending and receiving SMS.

GSM Modem Sim 300 (Sending Text SMS)


Hi guys, I just arrived from my elder brothers ring ceremony(thank God for making it successful) & I was
thinking on which topic I should write, suddenly my eyes caught the GSM modem kept on the corner of my
desk. So I decided to write about it.

I had the opportunity to work on GSM modem at the time of my major project in my engineering. My
project was Vehicle Crash Monitoring System. The motive was to create a device which will automatically
detect the accident and call for help at the emergency no.. It is a new idea & I had to work hard on it. I had
to use GSM modem for sending text sms on emergency number. Thus it call for help when it detects the
accident of the vehicle.
For my project, I used SIM 300. This is tri-band, slim and compact so that it could be used in compact
devices. I brought it for Rs.1600 (or 28.8$ approx) from a local shop.
Now about the hardware, it consists of a DB9 port for communicating with the computer or with the microcontroller, a jack for power, a integrated module, a connector and a micro strip antenna , an interface circuit
of Max 232. I am also posting the picture of my modem which is shown below.

So, to work with the modem you have to make an interfacing circuit on Max 232, which will convert the ttl
logic level from the micro-controller to RS 232 level, which is 9 or 12 volts. But making that circuit was a
tedious task for me, so I used another trick. I found out the tx and rx pins of ttl level in Max 232 in the
modem & soldered 2 wires from it. Also a 3rd wire from the ground of the circuit. Then I connected those
wires with the respective pins of my micro-controller & here I was ready to use my modem.
First thing to know before working on any GSM modem is to get familiarized with the at commands.
Embedded cellular modules(GSM Modems) are mainly controlled by the use of AT commands. AT or
Attention Commands are derived from the Hayes Command set (or AT command set) from 1977 to control
the 300-baud Hayes Smartmodem. They are a set of command-language or instructions that are sent to a
cellular module to perform different actions. Without AT commands one could not work with the modems.
Here I will show you how to program your micro-controller for sending text message. The essential
commands which will be used are:
AT+CMGF=1 // this command will instruct SIM300 module to enter text mode. After giving command
you should press enter key or send it ascii 0x0D character.
AT+CMGS=xxxxxxxxxx // xxxxxxxxxx is the phone number. after this command press enter or send
its ascii 0x0D character through micro-controller.

Now I will show you the code which I used with my arduino for sending SMS. The code is given below:
// The code is developed by Abishai for sending text message by using Sim300.
void setup(){
Serial.begin(9600); // the GPRS baud rate
delay(2500);
Serial.println(AT); //To check if GSM module is working
delay(2000);
Serial.println(AT+CMGF=1); // set the SMS mode to text
delay(1500);
}
void loop(){
delay(1500);
Serial.print(AT+CMGS=);
Serial.print(34,BYTE); //ASCII of
Serial.print(+919406686543);
Serial.println(34,BYTE);
delay(1500);
Serial.println(This is a sms from Abishai . just saying hello.); //this is the message to be sent
delay(1500);
Serial.println(26,BYTE); //Ascii code of ctrl+z to send the message
while(1);
}

How to interface GSM with 8051 microcontroller to send SMS?

#include<reg51.h>
unsigned char *command = "AT";
unsigned char *echo = "ATE0";
unsigned char *msgConfig = "AT+CMGF=1";
unsigned char *number = "AT+CMGS=\"8283******\"";
unsigned char *message = "hello";
unsigned char CTRLZ = 0x1A;
void serial_init(void);
void serial(unsigned char);
void puts(unsigned char *p );
void delay(void);
void main()
{
serial_init();
puts(command);
delay(); // delay of approx 1 sec
puts(echo);
delay();
puts(msgConfig);
delay();
puts(number);
delay();
puts(message);
delay();
puts(CTRLZ);
while(1);
}
void serial_init(void)
{
TMOD=0x20; //timer 1, mode 2(8-bit autoreload) to set baud rate
TH1=0xFD; //-3 to TH1 for 9600 baud rate
SCON=0x50; // 8 bit txion, 1 start 1 stop bit, REN enable for both txfr and rxve
TR1=1; // start timer
}
void puts(char *p)
{
char *temp = p; /*temp pointer so that the actual pointer is not displaced */
while(*temp != 0x00)
{
serial(*temp);
temp++;
}
}
void serial(unsigned char x)
{
SBUF=x;
while(TI==0);
TI=0;
}
void delay(void) // delay for approx 1 sec
{

int i;
TMOD=0x01; // timer 0 in mode 1
for(i=0;i<142;i++)
{
TL0=0x00; // starting value from 0
TH0=0x00;
TR0=1; // start timer
while(TF0==0); // polling TF flag for high
TR0=0; // stop timer
TF0=0; // clear flag TF0
}

Correction required in the above programme

You should not use delay, sleep or similar to wait for the response from the
modem! In the same way you hopefully never would think of writing a web
browser that ignores all responses the web server sends back to you, you
should never think of writing a modem communication program that ignores all
responses the modem sends back to you.

You MUST change your algorithm to the following:

send_at_command("AT+WHATEVER\r");
do {
line = read_full_line();
} while (!is_final_result_code(line));

where read_full_line reads character by character until it receives \n and the


previous character was \r (assuming V1 format1).

You can look at the code for atinout for an example for the is_final_result_code
function (you can also compare to isFinalResponseError and
isFinalResponseSuccess in ST-Ericsson's U300 RIL, although note that CONNECT
is not a final result code, it is an intermediate result code, so the name
isFinalResponseSuccess is not 100% correct).

Also, specifically for AT+CMGS, you MUST wait for the \r\n> response from the
modem before you start sending the payload.

Waiting for a text message (SMS)


When a text message (SMS) arrives on SIM300 GSM Module it sends a unsolicited
response <CR><LF>+CMTI: <mem>,<n><CR><LF>
I have already told in previous article that <CR> refers to a control character whose ASCII is
0D (Hex) and <LF> with ASCII code of 0A(Hex). The new thing you will learn about
is unsolicited response. Earlier I told commands are followed by response. But the response
discussed above is not followed by any command, it can come at any moment. So it is called
an unsolicited response.

value of mem is the storage location where the sms was stored. Usually its value is SM, which
stands for SIM memory.
the value of n is the sms slot on which the incoming message was stored. Depending on the
size of storage in your SIM card their may me 20 or so slots in your card. When a message is
received it is stored in the lowest numbered empty slot. For example you first received 4
messages then deleted the 1st message, then 5th message will get stored in slot 1.
Code Example showing how Wait for a message.

int8_t SIM300WaitForMsg(uint8_t *id)


{
//Wait for a unsolicited response for 250ms
uint8_t len=SIM300WaitForResponse(250);

if(len==0)
return SIM300_TIMEOUT;

sim300_buffer[len-1]='\0';

//Check if the response is +CMTI (Incoming msg indicator)


if(strncasecmp(sim300_buffer+2,"+CMTI:",6)==0)
{
char str_id[4];

char *start;

start=strchr(sim300_buffer,',');
start++;

strcpy(str_id,start);

*id=atoi(str_id);

return SIM300_OK;
}
else
return SIM300_FAIL;
}

Code Walkthrough
1. We wait for a response from SIM300 with a time-out of 250 millisecond. That means if
nothing comes for 250 millisecond we give up!
2. If we get a response, SIM300WaitForResponse() returns its length till trailing <CR>. So
suppose we got <CR><LF>+CMTI: SM,1<CR><LF> then len will be 14.
3. Next line sim300_buffer[len-1]='\0'; puts an NULL character at position len 1 that is
13(points to last <CR>). So the response actually becomes <CR><LF>+CMTI: SM,1
4. Now we want to check if the first 6 characters are +CMTI: or not, we check first 6
characters only because the <n> following +CMTI is variable. Remember it is the slot
number where the message is stored! Also while comparing we want to ignore the case,
that means +CMTI or +cMtI are same. This type of string comparison is easily done
using the standard C library function strncasecmp(). Well if you have ever attended a
C training session in school you must have remembered strcmp() , so you can
look strncasecmp().So you can see only an n and case is added in the name of the
function. n in the name indicate you dont have to compare the whole string, you can
check the first n characters. While the case in the name indicate a case in-sensitive
match. Also you notice we dont passsim300_buffer (which holds the response)
directly to the comparison function, but we passsim300_buffer + 2, this removes the
leading <CR><LF> in the response string.
5. If the response matches the next step is to extract the value of <n>, i.e. the message
slot id. As you can see the slot id is after the first comma(,) in the response. So we
search for the position of first comma in the response. This is done
using strchr() standard library function. Now start points to a string which is ",1".
6. The we do start++, this makes start points to a string which is "1", but remember it is
still a string. So we use standard library function atoi() which converts a string to a
integer. Which we store in *id. Remember the parameter id is pass by reference type, if
you dont know what does that means go and revise your C book!
7. Finally we return SIM300_OK which is a constant defined in sim300.h indicating a
success to caller.

Reading the Content of Text Message


The command that is used to read a text message from any slot is AT+CMGR=<n> where
<n> is an integer value indicating the sms slot to read. As I have already discussed that their
are several slots to hold incoming messages.
The response is like this
+CMGR: "STATUS","OA",,"SCTS"<CR><LF>Message
Body<CR><LF><CR><LF>OK<CR><LF>

where STATUS indicate the status of message it could be REC UNREAD or REC READ
OA is the Originating Address that means the mobile number of the sender.
SCTS is the Service Center Time Stamp.
This is a simple example so we discard the first line data i.e. STATUS, OA and SCTS. We only
read the Message Body.
One of the most interesting thing to note is that three things can happen while attempting to
read a message ! They are listed below.
1. Successful read in that case the response is like that discussed above.
2. Empty slot ! That means an attempt has been make to read a slot that does not have
any message stored in it. In this case the response is <CR><LF>OK<CR><LF>
3. SIM card not ready! In this case +CMS ERROR: 517 is returned.
Our function handles all the three situations.

int8_t SIM300ReadMsg(uint8_t i, char *msg)


{
//Clear pending data in queue
UFlushBuffer();

//String for storing the command to be sent


char cmd[16];

//Build command string


sprintf(cmd,"AT+CMGR=%d",i);

//Send Command
SIM300Cmd(cmd);

uint8_t len=SIM300WaitForResponse(1000);

if(len==0)
return SIM300_TIMEOUT;

sim300_buffer[len-1]='\0';

//Check of SIM NOT Ready error


if(strcasecmp(sim300_buffer+2,"+CMS ERROR: 517")==0)
{
//SIM NOT Ready
return SIM300_SIM_NOT_READY;
}

//MSG Slot Empty


if(strcasecmp(sim300_buffer+2,"OK")==0)
{
return SIM300_MSG_EMPTY;
}

//Now read the actual msg text


len=SIM300WaitForResponse(1000);

if(len==0)
return SIM300_TIMEOUT;

sim300_buffer[len-1]='\0';
strcpy(msg,sim300_buffer+1);//+1 for removing trailing LF of prev line

return SIM300_OK;
}

Code Walkthrough
1. Clear pending data in the buffer.
2. A command string is built using the standard library function sprintf().
1. sprintf(cmd,"AT+CMGR=%d",i);
2. You must be knowing that the above code gives a string in which placeholder %d
is replaced by the value of i.
3. Command is sent to the SIM300 module.
4. Then we wait for the response.
5. Response is analyzed.

6. Finally messages is read and copied to the memory address pointed by *msg using
standard library function strcpy().

Sending a New Text Message


We will develop a function to easily send message to any mobile number. This function has the
argument

num (IN) Phone number where to send the message ex "+919939XXXXXX"

msg (IN) Message Body ex "This a message body"

msg_ref (OUT) After successful send, the function stores a unique message reference
in this variable.

The function returns an integer value indicating the result of operation which may be

SIM300_TIMEOUT When their is some problem in communication line or the GSM


module is not responding or switched off.

SIM300_FAIL Message Sending Failed. A possible reason may be not enough balance in
your prepaid account !

SIM300_OK Message Send Success!

int8_t SIM300SendMsg(const char *num, const char *msg,uint8_t *msg_ref)


{
UFlushBuffer();

char cmd[25];

sprintf(cmd,"AT+CMGS= %s",num);

cmd[8]=0x22; //"

uint8_t n=strlen(cmd);

cmd[n]=0x22; //"
cmd[n+1]='\0';

//Send Command
SIM300Cmd(cmd);

_delay_ms(100);

UWriteString(msg);

UWriteData(0x1A);

//Wait for echo


while( UDataAvailable()<(strlen(msg)+5) );

//Remove Echo
UReadBuffer(sim300_buffer,strlen(msg)+5);

uint8_t len=SIM300WaitForResponse(6000);

if(len==0)
return SIM300_TIMEOUT;

sim300_buffer[len-1]='\0';

if(strncasecmp(sim300_buffer+2,"CMGS:",5)==0)
{

*msg_ref=atoi(sim300_buffer+8);

UFlushBuffer();

return SIM300_OK;
}
else
{
UFlushBuffer();
return SIM300_FAIL;
}
}

Code Walkthrough

1. The beginning of the function implementation is similar to those done above, first we
flush the buffer and build command string. Command string must be like this :o

AT+CMGS=<DA>, Where DA is the destination address i.e. the mobile number


like AT+CMGS="+919939XXXXXX"

This function sprintf(cmd,"AT+CMGS= %s",num); gives a string like this AT+CMGS=


+919939XXXXXX

cmd[8]=0x22; //" this like replaces the space just before +91 with " so we have a

string like this AT+CMGS="+919939XXXXXX


o

cmd[n]=0x22; //" this adds a " in the end also so the string becomes
AT+CMGS="+919939XXXXXX", but caution it removes the '\0' the null character that
must be present to mark the end of string in C. So the following statement adds a NULL
character at the end.

cmd[n+1]='\0';

2. Then we send the command string prepared above.\


3. We now write the message body to SIM300 module using the function UWriteString(msg);
4. UWriteData(0x1A);Is used to send the control character called EOF (End of File) to mark
the end of message.
5. Since SIM300 echoes back everything we write to it, so we remove the echo by reading
the data from the buffer.
6. Finally we wait for the response, read the response and compare it to find out whether
we succeeded or not.

Deleting a Text Message


This function takes an integer input which should be slot number of the message you wish to
delete. Function may return the following values.

SIM300_TIMEOUT When their is some problem in communication line or the GSM


module is not responding or switched off.

SIM300_FAIL Message Deleting Failed. A possible reason may be an incorrect slot


number id.

SIM300_OK Message Delete Success!

AT command of deleting a message is AT+CMGD=<n> where n is an slot of number of


message you wish to delete. If delete is successful it returns OK. The function implementation

is very simple compared to above functions. The steps are similar, that involves building a
command string, sending command, waiting for response and verifying response.

int8_t SIM300DeleteMsg(uint8_t i)
{
UFlushBuffer();

//String for storing the command to be sent


char cmd[16];

//Build command string


sprintf(cmd,"AT+CMGD=%d",i);

//Send Command
SIM300Cmd(cmd);

uint8_t len=SIM300WaitForResponse(1000);

if(len==0)
return SIM300_TIMEOUT;

sim300_buffer[len-1]='\0';

//Check if the response is OK


if(strcasecmp(sim300_buffer+2,"OK")==0)
return SIM300_OK;
else
return SIM300_FAIL;
}

SIM300 Message Send Receive Demo


To show all the above functions in working demo we have developed a small program. This
program does all the basic routine task on boot up, that include the following :

Initialize the LCD Module and the SIM300 GSM Module.

Print IMEI, Manufacturer name and model name.

Then it checks SIM card presence and connects to network.

When network connection succeeds its show name of the network. Eg. Airtel or
Vodafone etc.

Finally it sends a message with message body "Test".

Then it waits for a message, when a message arrives reads it and displays on LCD.

Then the message is deleted.

/******************************************************************************

A basic demo program showing sms functions.

NOTICE
-------NO PART OF THIS WORK CAN BE COPIED, DISTRIBUTED OR PUBLISHED WITHOUT A
WRITTEN PERMISSION FROM EXTREME ELECTRONICS INDIA. THE LIBRARY, NOR ANY PART
OF IT CAN BE USED IN COMMERCIAL APPLICATIONS. IT IS INTENDED TO BE USED FOR
HOBBY, LEARNING AND EDUCATIONAL PURPOSE ONLY. IF YOU WANT TO USE THEM IN
COMMERCIAL APPLICATION PLEASE WRITE TO THE AUTHOR.

WRITTEN BY:
AVINASH GUPTA
me@avinashgupta.com

*******************************************************************************/

#include <avr/io.h>
#include <util/delay.h>

#include "lib/lcd/lcd.h"
#include "lib/sim300/sim300.h"

void Halt();

int main(void)
{
//Initialize LCD Module
LCDInit(LS_NONE);

//Intro Message
LCDWriteString("SIM300 Demo !");
LCDWriteStringXY(0,1,"By Avinash Gupta");

_delay_ms(1000);

LCDClear();

//Initialize SIM300 module


LCDWriteString("Initializing ...");
int8_t r= SIM300Init();

_delay_ms(1000);

//Check the status of initialization


switch(r)
{
case SIM300_OK:
LCDWriteStringXY(0,1,"OK !");
break;
case SIM300_TIMEOUT:
LCDWriteStringXY(0,1,"No response");
Halt();
case SIM300_INVALID_RESPONSE:
LCDWriteStringXY(0,1,"Inv response");
Halt();
case SIM300_FAIL:
LCDWriteStringXY(0,1,"Fail");
Halt();
default:
LCDWriteStringXY(0,1,"Unknown Error");

Halt();
}

_delay_ms(1000);

//IMEI No display
LCDClear();

char imei[16];

r=SIM300GetIMEI(imei);

if(r==SIM300_TIMEOUT)
{
LCDWriteString("Comm Error !");
Halt();
}

LCDWriteString("Device IMEI:");
LCDWriteStringXY(0,1,imei);

_delay_ms(1000);

//Manufacturer ID
LCDClear();

char man_id[48];

r=SIM300GetManufacturer(man_id);

if(r==SIM300_TIMEOUT)
{
LCDWriteString("Comm Error !");
Halt();
}

LCDWriteString("Manufacturer:");

LCDWriteStringXY(0,1,man_id);

_delay_ms(1000);

//Manufacturer ID
LCDClear();

char model[48];

r=SIM300GetModel(model);

if(r==SIM300_TIMEOUT)
{
LCDWriteString("Comm Error !");
Halt();
}

LCDWriteString("Model:");
LCDWriteStringXY(0,1,model);

_delay_ms(1000);

//Check Sim Card Presence


LCDClear();
LCDWriteString("Checking SIMCard");

_delay_ms(1000);

r=SIM300IsSIMInserted();

if (r==SIM300_SIM_NOT_PRESENT)
{
//Sim card is NOT present
LCDWriteStringXY(0,1,"No SIM Card !");

Halt();
}
else if(r==SIM300_TIMEOUT)
{
//Communication Error
LCDWriteStringXY(0,1,"Comm Error !");

Halt();
}
else if(r==SIM300_SIM_PRESENT)
{
//Sim card present
LCDWriteStringXY(0,1,"SIM Card Present");

_delay_ms(1000);
}

//Network search
LCDClear();
LCDWriteStringXY(0,0,"SearchingNetwork");

uint8_t

nw_found=0;

uint16_t tries=0;
uint8_t

x=0;

while(!nw_found)
{
r=SIM300GetNetStat();

if(r==SIM300_NW_SEARCHING)
{
LCDWriteStringXY(0,1,"%0%0%0%0%0%0%0%0%0%0%0%0%0%0%0%0");
LCDWriteStringXY(x,1,"%1");
LCDGotoXY(17,1);

x++;

if(x==16) x=0;

_delay_ms(50);

tries++;

if(tries==600)
break;
}
else
break;

}
LCDClear();

if(r==SIM300_NW_REGISTERED_HOME)
{
LCDWriteString("Network Found");
}
else
{
LCDWriteString("Cant Connt to NW!");
Halt();
}

_delay_ms(1000);

LCDClear();

//Show Provider Name


char pname[32];
r=SIM300GetProviderName(pname);

if(r==0)
{
LCDWriteString("Comm Error !");
Halt();

LCDWriteString(pname);

_delay_ms(1000);

//Send MSG
LCDClear();
LCDWriteString("Sending Msg");

uint8_t ref;

r=SIM300SendMsg("+919939XXXXXX","Test",&ref);//Change phone number to some valid value!

if(r==SIM300_OK)
{
LCDWriteStringXY(0,1,"Success");
LCDWriteIntXY(9,1,ref,3);
}
else if(r==SIM300_TIMEOUT)
{
LCDWriteStringXY(0,1,"Time out !");
}
else
{
LCDWriteStringXY(0,1,"Fail !");
}

_delay_ms(2000);

//Wait for MSG


uint8_t id;

UFlushBuffer();

while(1)

{
LCDClear();

LCDWriteStringXY(0,0,"Waiting for msg");

x=0;
int8_t vx=1;

while(SIM300WaitForMsg(&id)!=SIM300_OK)
{
LCDWriteStringXY(0,1,"%0%0%0%0%0%0%0%0%0%0%0%0%0%0%0%0");
LCDWriteStringXY(x,1,"%1");
LCDGotoXY(17,1);

x+=vx;

if(x==15 || x==0) vx=vx*-1;


}

LCDWriteStringXY(0,1,"MSG Received

_delay_ms(1000);

//Now read and display msg


LCDClear();
char msg[300];

r=SIM300ReadMsg(id,msg);

if(r==SIM300_OK)
{

LCDWriteStringXY(0,0,msg);

_delay_ms(3000);

");

else
{
LCDWriteString("Err Reading Msg !");

_delay_ms(3000);

//Finally delete the msg


if (SIM300DeleteMsg(id)!=SIM300_OK)
{
LCDWriteString("Err Deleting Msg !");

_delay_ms(3000);
}

Halt();
}

void Halt()
{
while(1);
}

GSM Module Interfacing with 8051 Microcontroller

GSM Module Interfacing with 8051 Microcontroller (AT89S52)

GSM module is used in many communication devices which are based on GSM
(Global System for Mobile Communications) technology. It is used to interact with GSM
network using a computer. GSM module only understands AT commands, and can
respond accordingly. The most basic command is AT, if GSM respond OK then it is
working good otherwise it respond with ERROR. There are various AT commands
like ATA for answer a call, ATD to dial a call, AT+CMGR to read the message,
AT+CMGS to send the sms etc. AT commands should be followed by Carriage return
i.e. \r (0D in hex), like AT+CMGS\r. We can use GSM module using these
commands.

GSM Interfacing with 8051(AT89S52)


Instead of using PC, we can use microcontrollers to interact with GSM module and
LCD to get the response from GSM module. So we are going to interface GSM with a
8051 microcontroller(AT89S52). Its very easy to interface GSM with 8051, we just
need to send AT commands from microcontroller and receive response from GSM and
display it on LCD. We can use microcontrollers serial port to communicate with GSM,
means using PIN 10 (RXD) and 11 (TXD).

First we need to connect LCD to 8051, you can learn this from here: LCD Interfacing
with 8051 Microcontroller. Then we need to connect GSM module to 8051, now here
we should pay some attention. First you need to check that whether your GSM module
is capable of working at TTL logic or it can only work with RS232. Basically if your
module has RX and TX (with GND) Pins on board then it can work on TTL logic. And If
it dont have any RX,TX pins and only have a RS232 port (serial port with 9) then you
need

to

use

MAX232

IC

to

connect

serial

port

to

the

microcontroller.

BasicallyMAX232 used to convert serial data into TTL logic because Microcontroller

can only work on TTL logic. But if GSM module has RX, TX pins then you dont need
to use MAX232 or any serial converter, you can directly connect RX of GSM to TX
(PIN 11) of 8051 and TX of GSM to RX (PIN 10) of 8051. In our case I have
used SIM900A module and it has RX, TX pins so I havent used MAX232.

Circuit Diagram for GSM interfacing with AT89S52 microcontroller is shown in


above figure. Now after the connection, we just need to write program to send AT
commands to GSM and receive its response on LCD. There are many AT commands
as described above, but our scope of this article is just to interface GSM with 8051, so
we are just going to send command AT followed by \r (0D in hex). This will give us a
response OK. But you can extend this program to use all the facilities of GSM.

Code explanation
Besides all the LCD related functions, here we have used Serial port and timer mode
register (TMOD). You can learn about LCD functions and other code by going through
our 8051 projects section, here I am explaining about serial communication related
code functions:
GSM_init() function:

This function is use to set the Baudrate for microcontroller. Baudrate is nothing but the
Bits/second transmitted or received. And we need to match the baudrate of 8051 to the
Baud rate of GSM module i.e. 9600. We have used the Timer 1 in Mode 2 (8-bit autoreload mode) by setting the TMOD register to 0X20 and Higher byte of Timer 1(TH1) to
0XFD to get the baud rate of 9600. Also SCON register is used to set the mode of
serial communication, we have used Mode1 (8-bit UART) with receiving enabled.
GSM_write Function:
SBUF (serial buffer special function register) is used for serial communication,
whenever we want to send any byte to serial device we put that byte in SBUF register,
when the complete byte has been sent then TI bit is set by hardware. We need to reset
it for sending next byte. Its a flag that indicates that byte has been sent successfully. TI
is the second bit of SCON register. We have sent AT using this function.
GSM_read function:
Same as sending, whenever we receive any byte from external device that byte is put
in SBUF register, we just need to read it. And whenever the complete byte has been
received RI bit is set by hardware. We need to reset it for receiving next byte. RI is the
first bit of SCON register. We have read response OK using this function.

Code:
#include<reg52.h>
#define display_port P2

//Data pins connected to port 2 on microcontroller

sbit rs = P3^2; //RS pin connected to pin 2 of port 3


sbit rw = P3^3; // RW pin connected to pin 3 of port 3
sbit e = P3^4; //E pin connected to pin 4 of port 3
int k;
unsigned char str[26];
void GSM_init()

// serial port initialization

{
TMOD=0x20;
TH1=0xfd;
SCON=0x50;
TR1=1;

// Timer 1 selected, Mode 2(8-bit auto-reload mode)


// 9600 baudrate
// Mode 1(8-bit UART), receiving enabled
// Start timer

}
void msdelay(unsigned int time) // Function for creating delay in milliseconds.

{
unsigned m,n ;
for(m=0;m<time;m++)
for(n=0;n<1275;n++);
}
void lcd_cmd(unsigned char command) //Function to send command instruction to LCD
{
display_port = command;
rs= 0;
rw=0;
e=1;
msdelay(1);
e=0;
}
void lcd_data(unsigned char disp_data) //Function to send display data to LCD
{
display_port = disp_data;
rs= 1;
rw=0;
e=1;
msdelay(1);
e=0;
}
void lcd_init()

//Function to prepare the LCD and get it ready

{
lcd_cmd(0x38); // for using 2 lines and 5X7 matrix of LCD
msdelay(10);
lcd_cmd(0x0F); // turn display ON, cursor blinking
msdelay(10);
lcd_cmd(0x01); //clear screen
msdelay(10);
lcd_cmd(0x80); // bring cursor to beginning of first line
msdelay(10);
}
void lcd_string(unsigned char *str)
{
int i=0;

// Function to display string on LCD

while(str[i]!='\0')
{
lcd_data(str[i]);
i++;
msdelay(10);
if(i==15) lcd_cmd(0xc2);
}
return;
}
void GSM_write(unsigned char ch)

// Function to send commands to GSM

{
SBUF=ch;

// Put byte in SBUF to send to GSM

while(TI==0);
TI=0;

//wait until the byte trasmission

//clear TI to send next byte.

}
void GSM_read()

// Function to read the response from GSM

{
while(RI==0); // Wait until the byte received
str[k]=SBUF;
RI=0;

//storing byte in str array

//clear RI to receive next byte

}
void main()
{
k=0;
lcd_init();
GSM_init();
msdelay(200);
lcd_string("Interfacing GSM with 8051");
msdelay(200);
lcd_cmd(0x01);

//

Clear LCD screen

msdelay(10);
GSM_write('A');

// Sending 'A' to GSM module

lcd_data('A');
msdelay(1);
GSM_write('T');
lcd_data('T');

// Sending 'T' to GSM module

msdelay(1);
GSM_write(0x0d);

// Sending carriage return to GSM module

msdelay(50);
while(1)
{
GSM_read();
if(str[k-1]=='O' && str[k]=='K'){
lcd_data(0x20);
lcd_data(str[k-1]);
lcd_data(str[k]);
break;
}
k=k+1;
}
}

// Write 'Space'