Wednesday 28 November 2018

Giao Tiếp Modul SIM900A

Giới thiệu

Hệ thống thông tin di động toàn cầu (GSM) là một hệ thống di động kỹ thuật số được sử dụng cho các thiết bị di động. Nó là một tiêu chuẩn quốc tế cho điện thoại di động được sử dụng rộng rãi cho truyền thông đường dài.
Có nhiều mô-đun GSM có sẵn trên thị trường như SIM900, SIM700, SIM800, SIM808, SIM5320, v.v.
Mô-đun SIM900A cho phép người dùng gửi / nhận dữ liệu qua GPRS, gửi / nhận SMS và thực hiện / nhận cuộc gọi thoại.
Nó truyền đạt serially với các thiết bị như một vi điều khiển, PC sử dụng lệnh AT.
Để giao diện mô-đun SIM900A với mạng di động, nó yêu cầu thẻ SIM được cung cấp bởi nhà điều hành mạng.
Mô-đun GSM / GPRS sử dụng giao tiếp USART để giao tiếp với vi điều khiển hoặc thiết bị đầu cuối PC.
Để biết thông tin về UART trong 8.051 và cách sử dụng nó, hãy tham khảo chủ đề  UART trong 8.051 trong phần 8051 Inside.

Sơ đồ giao tiếp

Giao diện SIM900A GSM Module với 8051

Ứng dụng
Hãy thiết kế một ứng dụng nhỏ trong đó người dùng sẽ nhận được SMS “gọi cho tôi” và người dùng sẽ tự động gọi người gửi tin nhắn đó.
Chương trình

#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;
 }
}



Code mô phỏng
Tệp đính kèm

No comments:

Post a Comment