PIC16F877A with SIM800L AT command ERROR

Thread Starter

Gaurav Gupta_1568212829

Joined Sep 11, 2019
22
I am using SIM800L with PIC16F877A. I have developed the code to send AT commands but it always shows ERROR. What I am missing?

The Baud rate is set to 9600 on 20MHz external crystal oscillator
SPBRG = 129
BRGH = 1
_XTAL_FREQ 20000000


Code:
// PIC16F877A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define _XTAL_FREQ 20000000

char buff[50], a = 0;
char b;
int conn=0;
int i;

#define RS RD0
#define RW RD1
#define EN RD2

void lcd_cmd(unsigned char cmd)
{
    PORTD = (0xF0 & cmd);
    RS = 0;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
   
    PORTD = (cmd<<4);
    RS = 0;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
}

void lcd_data(unsigned char data)
{
    PORTD = (0xF0 & data);
    RS = 1;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
   
    PORTD = (data<<4);
    RS = 1;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
}

void lcd_string(char *str)
{
    while(*str != '\0')
    {
        lcd_data(*str++);
    }
}

void lcd_init()
{
    lcd_cmd(0x02);//return to home
    lcd_cmd(0x28);///4bitmode
    lcd_cmd(0x0C);///cursor off
    lcd_cmd(0x06);///increment cursor
    lcd_cmd(0x01);///display clear
}


void uart_init()
{
    TXSTAbits.TXEN = 1;     ////enable transmission
    TXSTAbits.BRGH = 1;     ////high speed selection bit
   
    RCSTAbits.CREN = 1;     ////continuous receive enable
   
    SPBRG = 129;            ////baud rate generation 9600 at 20MHz crystal
    TRISCbits.TRISC7 = 1;   ////enable receive(input) on RC7
    TRISCbits.TRISC6 = 0;   ////enable transmit(output) on RC6
   
    RCSTAbits.SPEN = 1;     ////enable UART
   
    GIE = 1;                ///enable UART related interrupts
    PEIE = 1;
    RCIE = 1;
}


void gsm_send_char(unsigned char data)
{
    TXREG = data;
    while(PIR1bits.TXIF ==0);
}

char gsm_receive_char()
{
    while(PIR1bits.RCIF == 0);
    return (RCREG);
}

void gsm_send_string(char *data)
{
    while(*data != '\0')
    {
        gsm_send_char(*data++);
    }
}

__interrupt() void uart(void)
{
    if(RCIF)
    {
        RCIF = 0;
        b = RCREG;
        buff[a] = b;
        a++;
       
        GIE = 1;
        RCIE = 1;
        PEIE = 1;
               
    }
}

void gsm_init()
{
    if(conn == 0)
    {
        a=0;
        gsm_send_string("AT\r");
        __delay_ms(500);
        if(strstr(buff, "OK"))
        {
            lcd_cmd(0x80);
            lcd_string(buff);
            //a=0;
            memset(buff, 0, sizeof(buff));
        }
       
        else
        {
            lcd_cmd(0x80);
            lcd_string("AT ERROR");
        }
    }
}

void main(void)
{
    TRISD = 0x00;
    lcd_init();
    uart_init();
   
    lcd_cmd(0x80);
    lcd_string("GSM");
   
    while(1)
    {
        gsm_init();
        __delay_ms(2000);
    }
    return;
}
 

Picbuster

Joined Dec 2, 2013
1,047
I am using SIM800L with PIC16F877A. I have developed the code to send AT commands but it always shows ERROR. What I am missing?

The Baud rate is set to 9600 on 20MHz external crystal oscillator
SPBRG = 129
BRGH = 1
_XTAL_FREQ 20000000


Code:
// PIC16F877A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define _XTAL_FREQ 20000000

char buff[50], a = 0;
char b;
int conn=0;
int i;

#define RS RD0
#define RW RD1
#define EN RD2

void lcd_cmd(unsigned char cmd)
{
    PORTD = (0xF0 & cmd);
    RS = 0;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
  
    PORTD = (cmd<<4);
    RS = 0;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
}

void lcd_data(unsigned char data)
{
    PORTD = (0xF0 & data);
    RS = 1;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
  
    PORTD = (data<<4);
    RS = 1;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
}

void lcd_string(char *str)
{
    while(*str != '\0')
    {
        lcd_data(*str++);
    }
}

void lcd_init()
{
    lcd_cmd(0x02);//return to home
    lcd_cmd(0x28);///4bitmode
    lcd_cmd(0x0C);///cursor off
    lcd_cmd(0x06);///increment cursor
    lcd_cmd(0x01);///display clear
}


void uart_init()
{
    TXSTAbits.TXEN = 1;     ////enable transmission
    TXSTAbits.BRGH = 1;     ////high speed selection bit
  
    RCSTAbits.CREN = 1;     ////continuous receive enable
  
    SPBRG = 129;            ////baud rate generation 9600 at 20MHz crystal
    TRISCbits.TRISC7 = 1;   ////enable receive(input) on RC7
    TRISCbits.TRISC6 = 0;   ////enable transmit(output) on RC6
  
    RCSTAbits.SPEN = 1;     ////enable UART
  
    GIE = 1;                ///enable UART related interrupts
    PEIE = 1;
    RCIE = 1;
}


void gsm_send_char(unsigned char data)
{
    TXREG = data;
    while(PIR1bits.TXIF ==0);
}

char gsm_receive_char()
{
    while(PIR1bits.RCIF == 0);
    return (RCREG);
}

void gsm_send_string(char *data)
{
    while(*data != '\0')
    {
        gsm_send_char(*data++);
    }
}

__interrupt() void uart(void)
{
    if(RCIF)
    {
        RCIF = 0;
        b = RCREG;
        buff[a] = b;
        a++;
      
        GIE = 1;
        RCIE = 1;
        PEIE = 1;
              
    }
}

void gsm_init()
{
    if(conn == 0)
    {
        a=0;
        gsm_send_string("AT\r");
        __delay_ms(500);
        if(strstr(buff, "OK"))
        {
            lcd_cmd(0x80);
            lcd_string(buff);
            //a=0;
            memset(buff, 0, sizeof(buff));
        }
      
        else
        {
            lcd_cmd(0x80);
            lcd_string("AT ERROR");
        }
    }
}

void main(void)
{
    TRISD = 0x00;
    lcd_init();
    uart_init();
  
    lcd_cmd(0x80);
    lcd_string("GSM");
  
    while(1)
    {
        gsm_init();
        __delay_ms(2000);
    }
    return;
}
The most simple test method is to connect a pc to your PIC ( replace the GSM)
Use max 232 like chip when TTL signals are used to connect the gsm with pic.

make a loop in the pic like '1234567 \r\n' with an interval leat say 2 sec's.

Observe the results when rubbish change pc's baud rate redo.
When the correct baud rate is found check with the table's in the pic manual.
Some baud rates needs a different settings this caused by the way the dividers work.

Picbuster
 

Thread Starter

Gaurav Gupta_1568212829

Joined Sep 11, 2019
22
My PIC development board contains onboard CP2102. On your recommendation I developed the code and connected my board directly to the USB PORT and started sending from putty, it is printing "hello" when I send "hello".
Below is the code.

Code:
#include <xc.h>
#include <pic16f877a.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define _XTAL_FREQ 20000000

#define RS RD0
#define RW RD1
#define EN RD2


char buff[80], a;
int flag, b, i = 0;


void lcd_cmd(unsigned char cmd)
{
    PORTD = (0xF0 & cmd);
    RS = 0;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
  
    PORTD = (cmd<<4 & 0xf0);
    RS = 0;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
}

void lcd_data(unsigned char data)
{
    PORTD = (0xF0 & data);
    RS = 1;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
  
    PORTD = (data<<4 & 0xf0);
    RS = 1;
    RW = 0;
    EN = 1;
    __delay_ms(5);
    EN = 0;
}

void lcd_string(char *str)
{
    while(*str != '\0')
    {
        lcd_data(*str++);
    }
}

void lcd_init()
{
    lcd_cmd(0x02);//return to home
    lcd_cmd(0x28);///4bitmode
    lcd_cmd(0x0C);///cursor off
    lcd_cmd(0x01);///display clear
    lcd_cmd(0x06);///increment cursor

}

void uart_init()
{
    SPBRG = 129;
    BRGH = 1;
    SYNC = 0;
    SPEN = 1;
    TXEN = 1;
    CREN = 1;
  
    GIE = 1;
    PEIE = 1;
    RCIE = 1;
    RCIF = 0;
    //TXIE = 1;
  
    TRISC7 = 1;
    TRISC6 = 0;
}

void gsm_send_char(char data)
{
    TXREG = data;
    while(TXIF == 0);
  
}

char gsm_receive_char()
{
    while(PIR1bits.RCIF == 0);
    return RCREG;
}


void gsm_send_string(char *p)
{
    while(*p != '\0')
    {
        gsm_send_char(*p++);
    }
}

__interrupt() void isr(void)
{
    if(RCIF == 1)
    {
        a = RCREG;
        buff[i] = a;
        i++;
        RCIF = 0;
    }
}

void main(void)
{
    TRISD = 0x00;
    lcd_init();
    uart_init();
  
    lcd_cmd(0x80);
    lcd_string("GSM TESTING");
  
    while(1)
    {
        //i = 0;
        if(strstr(buff, "hello"))
        {
            lcd_cmd(0xC0);
            lcd_string(buff);
        }
    }
    return;
}
So here I guess my baud rate is correct and UART Receive is working fine.
 

ci139

Joined Jul 11, 2016
1,898
So here I guess my baud rate is correct and UART Receive is working fine.
  • there might be wiring differences (e.g. pin function differences for PC and for a specialized terminal device)
  • although the baud is auto detected by the sim800 the start stop parity (and the polarity of these 3 might vary from the one for PC)
  • ! but there's a lot of time passed when i was last busy by RSxxx comm. -- so i think i can't much advise for the "new stuff"
 
Top