View previous topic :: View next topic |
Author |
Message |
picfreak
Joined: 26 Oct 2009 Posts: 16
|
gsm response problem with pic |
Posted: Thu Nov 12, 2009 2:48 am |
|
|
i am usinf pic 16f877a ans using external crystal of 20Mhz
my gsm module works fine with hyperterminal and getting ok response for every at commands....
but when i connect to pic i can send at commands my message is delivered but i can not get any response form gsm module of ok... Code: |
#include "D:\avudai\gsm_app_design\response_877a.h"
int cmd_rep[5]={};
int i=0,set_flag=0,value;
#int_RDA
void RDA_isr(void)
{
cmd_rep[i]=getch();
i++;
output_high(pin_d7);
if(i==1)
{
set_flag=1;
i=0;
disable_interrupts(INT_RDA);
disable_interrupts(GLOBAL);
}
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
output_high(pin_d7);
delay_ms(1000);
output_low(pin_d7);
delay_ms(1000);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
printf("AT");
putc(0x0D);
putc(0x0A);
while(1)
{
if(set_flag==1)
{
for(i=0;i>=2;i++)
{
printf("%d",cmd_rep[i]);
}
}
}
}
i am getting response of at and trying to dispaly its not getting in to int_rda i given an led for indication ......
#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
|
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
expectable gsm response problem with incorrect programming |
Posted: Thu Nov 12, 2009 3:25 am |
|
|
I see two issues:
- your code receives only one character, then disables interrupts. Why?
- printf("AT");putc(0x0D);putc(0x0A); behaves very different from typing "AT<CR>" in Hyperterminal. The latter adjusts the modem baud rate to your terminal, the first doesn't. Read the modem manual to understand why. It has to do with necessary delays between characters for automatic baud rate detection. |
|
|
picfreak
Joined: 26 Oct 2009 Posts: 16
|
|
Posted: Thu Nov 12, 2009 4:18 am |
|
|
ya i have given delay between each AT commands
YA I HAVE CHANGED
Code: |
#int_RDA
void RDA_isr(void)
{
cmd_rep[i]=getch();
i++;
output_high(pin_d7);
if(i==2)
{
set_flag=1;
i=0;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
}
|
now i have enabled interrupts in isr_rda()
not working
command AT is getting displayed in hyper terminal
there is no ok response
it is not getting in to isr_rda()
ya i adjusted modem rate in hyperterminal
AT is displaying but modem response i am storing in ARRAY BUT NOTHING STORED IN ARRAY ... i have indicated by an led in pin_d7
pls guide me to get response of gsm
thanks in advance |
|
|
Guest
|
|
Posted: Thu Nov 12, 2009 4:34 am |
|
|
Your program has several problems.
Global variable 'i' is modified in both the main loop and in the interrupt routine. NEVER do this. Imagine what will happen when you are running the for-loop in main() and then a character is received, the interrupt will pre-empt main() and the variable i is modified. You will get unpredictable and dangerous results.
It is ok to read the variable in both main and the interrupt, but only write the it in one of both.
Add the ERRORS keyword to the #rs232 configuration line. This will help to reset UART Receive Buffer overflows. When more than 3 characters are buffered by the UART Receiver, the hardware will disable itself untill the error bits are reset. Adding the ERRORS keyword will clear these bits for you on every call to getc().
Code: | enable_interrupts(GLOBAL); | NEVER do this inside an interrupt handler. On entering an interrupt the hardware will disable interrupts to prevent recursion in case a second interrupt gets triggered. On exit of the interrupt routine the global interrupt flag is enabled again automatically. By executing this command you are overruling the hardware protection against recursion.
Code: | for(i=0;i>=2;i++)
{
printf("%d",cmd_rep[i]);
} | This loop will only get excecuted when i becomes >=2. This will never happen because in your interrupt handler you reset i to 0 as soon as it becomes 2.
There are a few more problems with the architecture of your code. I suggest that for a first simple test program you forget about interrupts, just call getc() from your main program.
When you have this working and need interrupts for higher performance, then have a look at the program ex_sisr.c in the Compiler's examples directory. This is an implementation of a circular receive buffer. Copy the code and in replace getc() with bgetc() and you are ready to go. |
|
|
|