1
\$\begingroup\$

I am trying to design a GPS car tracker with a SIM808 module using a STM32F103RET6 header board. I want to get the location link messaged to my phone by sending an SMS to the module.

Right now, my code works but only when I reset the board after sending each SMS.

I attached my code. Can you figure out what the problem is?

ps: I checked and figured out that after the first SMS the responses of sim808 are stored in str2 instead of str 1 !! I don't know why this is happening. Main program:

#include <stm32f10x.h>
#include "usart.h"
#include <string.h>
#include <stdio.h>  
#include <stdlib.h>
#include <stdint.h>

char S=0x1A;
#define Enter    usart_sendchar('\n');
#define CR       usart_sendchar('\r');
#define GIM      usart_sendchar('"');
#define SUB      usart_sendchar(S);
#include "stm32f10x.h"
#include <string.h>
char get_Enter = 0;
uint8_t ch;
 char str1[300];
char str2[100];
int i=0;
char flag=0;
char str_tmp[20];
char str_tmp2[20];
char* p;


volatile uint32_t msTicks;

//calling all the functions 

void Send_SMS(char *text);
void CMTI(void);
void wait_to_get(char ch);
void del_All_SMS(void);
void CMGF_1(void);
void Delay (uint32_t Time);
void CMGR (void);
void CGNSPWR_1(void);
void CGNSINF(void);
void interrupt_activation(void);
void CGNSINF_C(void);
void AT(void);
void Delay (uint32_t dlyTicks);
void SysTick_Handler(void);


// the interrupt handler for the systick module 
void SysTick_Handler(void) {
    msTicks++;
}
void Delay (uint32_t dlyTicks) {
    uint32_t curTicks;
    curTicks = msTicks;
    while ((msTicks - curTicks)< dlyTicks);
}








void Send_SMS(char *text)
{
CMGF_1(); 
Delay(500);       
str_tmp[0]='\0';
Delay(100);       

strcpy(str_tmp,"AT+CMGS=");
Delay(500);       
usart_sendstring(str_tmp);
GIM
str_tmp[0]='\0';
Delay(100);       

strcpy(str_tmp,"+98905xxxxxxx");
Delay(500);       
usart_sendstring(str_tmp);
GIM
Enter
CR

Delay(500);           

 usart_sendstring(text);
Enter
CR
str_tmp[0]='\0';
Delay(500);       
SUB

Delay(100);
del_All_SMS();
}
void USART1_IRQHandler(void) {

        ch = USART1->DR & 0xFF; 
    if (ch == '\n'){ // 13 enter
             
                  get_Enter =1;
        
         }
        else{
            str1[i]= ch;
            i++;
        }
 }


            
             
             
             
             
             
                 



    
    void CMGF_1(void)
 {
    str_tmp[0]='\0';
    Delay(100);       
    strcpy(str_tmp,"AT+CMGF=1");
    Delay(500);       
    usart_sendstring(str_tmp);
  Enter
    CR  
    
 }


 void del_All_SMS(void)
 {
str_tmp[0]='\0';
Delay(100);
strcpy(str_tmp,"AT+CMGD=1,4");
Delay(500);       
usart_sendstring(str_tmp);
Enter
CR   
}
 
 
    void CMGR(void)
 {
    str_tmp[0]='\0';
  
    Delay(100);      
    strcpy(str_tmp,"AT+CMGR=1");
  Delay(500);    
    usart_sendstring(str_tmp);
  Enter
    CR  
    
 }
    void CGNSINF(void)
 {
    str_tmp[0]='\0';
    Delay(100);       
    strcpy(str_tmp,"AT+CGNSINF");
    Delay(500);       
    usart_sendstring(str_tmp);
  Enter
    CR      
    
 }
void CGNSPWR_1(void)
 {
    str_tmp[0]='\0';
    Delay(100);       
    strcpy(str_tmp,"AT+CGNSPWR=1");
        Delay(500);
    usart_sendstring(str_tmp);
    Enter
    CR  
    
 }
 
 void AT(void)
 {
    str_tmp[0]='\0';  
    Delay(100);  
    strcpy(str_tmp,"AT");
        Delay(500);
    usart_sendstring(str_tmp);
    Enter
    CR  
    
 }
 
 
 
 
 
 
    
    
int main() 
    {
    SystemInit();
  SysTick_Config(SystemCoreClock/1000); // setup systick timer for 1ms interrupts
    usart_init();   
        
  AT();
        
        p=NULL;
         
            check:AT();
  
        Delay(2000);
        
        p=strstr(str1,"OK");   
        if(p==NULL) goto check;
        
             
  CMGF_1();
    Delay(500);

    CGNSPWR_1();
    
    Delay(500); 
  del_All_SMS();
    
    Delay(500);
        
    RCC->APB2ENR |= (1<<3); 
    GPIOB->CRL &= ~0xF;
  GPIOB->CRL |= 0x3;    
    
        
while (1)
{
    
    if (get_Enter ==1)
    {
      if (flag==0){
       ////waiting for +CMTI: from sim800
            do
     {  
      p=strstr(str1,"+CMTI:");   
      } 
         while(p==NULL);
      Delay(1000);
                // sending AT+CMGR=1 command
            if (p!=NULL)
            {
                    CMGR();
            
                    Delay(350);
                flag=1;
            }
        }
    if (flag==1) {
        p=strstr(str1,"+CMGR");
            if (p){
                p=strstr(str1,"loc");
                                
if (p!=NULL)
{

CGNSINF();
    Delay(300);
}
else if (p==NULL)
{
del_All_SMS();
memset(str1, 0, 300);   
    flag=0;
    
}
p=strstr(str1,"+CGNSINF:");
if (p)
{


float a[5];
          
char str2[80];
   const char s[2] = ",";
   char *token;
   // getting the lattitude and longitude 
   token = strtok(p, s);
   
    for (int i=0;i<5;i++){
      sprintf( str2," %s\n", token );
        a[i]=atof(str2);
    
      token = strtok(NULL, s);
    } 

sprintf(str2,"https://maps.google.com/?q=%.6f,%.6f",a[3],a[4]);
Send_SMS(str2);
p=NULL; 
del_All_SMS();
    flag=0;
memset(str1, 0, 300);




    } 



      } 
            
            
        } 
        }  
             
             
        } 
            
        
    }
 

The code for USART is:

#include "stm32f10x.h"
#include "usart.h"
    char str[200];
    char data;

//// initialize usart
void usart_init(void) 
 {

  RCC->APB2ENR |=  (   1UL <<  0);        /* enable clock Alternate Function  */
  AFIO->MAPR   &= ~(   1UL <<  2);        /* clear USART1 remap               */

  RCC->APB2ENR |=  (   1UL <<  2);        /* enable GPIOA clock               */
  GPIOA->CRH   &= ~(0xFFUL <<  4);        /* clear PA9, PA10                  */
  GPIOA->CRH   |=  (0x0BUL <<  4);        /* USART1 Tx (PA9) output push-pull */
  GPIOA->CRH   |=  (0x04UL <<  8);        /* USART1 Rx (PA10) input floating  */

  RCC->APB2ENR |=  (   1UL << 14);        /* enable USART#1 clock             */
  USART1->BRR=0x1D4C;   // 9600 @72MHz
//  USART1->BRR   = 0x0271;                 /* 115200 baud @ PCLK2 72MHz        */
  USART1->CR1   = ((   1UL <<  2) |       /* enable RX                        */
                   (   1UL <<  3) |       /* enable TX                        */
                   (   0UL << 12) );      /* 1 start bit, 8 data bits         */
  USART1->CR2   = 0x0000;                 /* 1 stop bit                       */
  USART1->CR3   = 0x0000;                 /* no flow control                  */

  USART1->CR1  |= ( 1 << 13);      /* enable USART                     */
    
    USART1->CR1  |= ( 1UL << 5);     // RXNE interrupt enable
    NVIC_SetPriority(USART1_IRQn,5); /* Default priority group 0, can be 0(highest) - 31(lowest) */
  NVIC_EnableIRQ(USART1_IRQn);     /* Enable UART0 Interrupt */
}





void usart_sendchar(char data){
    while(!(USART1->SR&(1<<7)));
    USART1->DR=data;
}
char usart_getchar(void) 
    {
        
    while (!(USART1->SR&(1<<5)));
    data=USART1->DR ;
  return data;      
    }


void usart_getstring(char *str) 
{

  char *temp = str;
    
    do{
        
        *temp = usart_getchar();
        usart_sendchar (*temp) ;
        
    } while(*(temp++) != 0x0D );
    *(temp-1) = 0;

}

void usart_sendstring(char *s) 
{
    while (*s) 
    {
    usart_sendchar(*s);
        s++;
    }
}

    
 
\$\endgroup\$
2
  • \$\begingroup\$ You need to find out where the problem is. It could be in the SIM808, it could be in your software, it could be in the power supply to the SIM808. Connect the SIM808 to a serial adapter then connect that to your computer. Send commands by hand and see if the SIM808 hangs. \$\endgroup\$
    – JRE
    Commented Aug 20, 2021 at 12:22
  • \$\begingroup\$ I checked with the serial adaptor and it works fine and also when I debug I came across a hard fault error \$\endgroup\$
    – salar1991
    Commented Aug 20, 2021 at 13:12

1 Answer 1

0
\$\begingroup\$

I fixed m problem the problem I had was the array that is filled in the interrupt can not be cleared outside the interrupt. I calculated how many characters are needed to send loc and receive the location and I changed the usart interrupt routine to the code as shown below.

 void USART1_IRQHandler(void) {

        ch = USART1->DR & 0xFF; 
//    if (ch == '\n'){ // 13 enter
             
    if (str1[346]!=NULL)                 {
             
            for (int j=0;j<400;j++)
        {
        
        str1[j]=0;
        
        
        }
        i=0;
    }
 else {     
            str1[i]= ch;
            i++;
 }


 
 }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.