View previous topic :: View next topic |
Author |
Message |
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
Please help me use #int_rda |
Posted: Thu Apr 29, 2010 4:20 am |
|
|
Hi. I'm working on a PIC to GSM project. I'm in the testing stages of the program. However I need to initialise the GSM phone before it can perform certain tasks. I'm using these AT commands. When the phone replies to the commands, my program freezes...
Code: | puts("at+clip=1");
delay_ms(500); // wait for phone to reply
puts("at+cpms=mt,mt,mt");
delay_ms(500); // wait for phone to reply
puts("at+csms=1");
delay_ms(500); // wait for phone to reply
puts("at+cnmi=1,2,0,0,1");
delay_ms(500); // wait for phone to reply
{
Main Program
} |
The program freezes by the second AT command. After a lot of reading I realised that I may need to use an Interrupt such as int_rda but I'm not sure how to use it.
Can anyone help please ? |
|
![](templates/subSilver/images/spacer.gif) |
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
|
Posted: Thu Apr 29, 2010 4:26 am |
|
|
Almost forgot I'm using PIC 16F876A @ 4MHZ and 2400 baudrate with CCS C v4.023 |
|
![](templates/subSilver/images/spacer.gif) |
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
|
Posted: Thu Apr 29, 2010 4:33 am |
|
|
Also
Code: | #use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7) |
I was reading that I need to include ERRORS directive ? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19360
|
|
Posted: Thu Apr 29, 2010 7:11 am |
|
|
The key point is in your own remark 'wait for phone to reply'.
The phone is replying, the hardware UART, has just _two_ characters of input buffer. This overflows, sets the 'overrun' error, and hangs the UART.
Adding 'ERRORS', will clear the overrun error that results _the next time you read the UART_, but not before. You need to be reading the characters from the UART, and either just throwing them away, or doing something with them (for instance, shouldn't you really be looking for the correct response from the UART to check that it _is_ actually responding?).
EX_SISR.c, shows a basic INT_RDA handler adding a software buffer to store the characters.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
|
Posted: Thu Apr 29, 2010 3:38 pm |
|
|
Ttelmah, thanks for your reply.
I've read the EX_SISR.c example but I don't fully understand how it works. I don't really care about the phone's responses and I would just like to get rid of the unwanted characters.
"You need to be reading the characters from the UART, and either just throwing them away"
It seems to be what I need but how can I incorporate the interrupt into my code so that I don't get the buffer overrun ?
PLEASE EXPLAIN THIS PART...
Code: | #int_rda
void serial_isr() {
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE; // ????????
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc() { // ??????????????
BYTE c;
while(!bkbhit) ;
c=buffer[next_out]; // ???????????
next_out=(next_out+1) % BUFFER_SIZE; // ?????????????
return(c);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Fri Apr 30, 2010 11:27 am |
|
|
Well buffer is defined as a global or at the top of main.
char buffer[64];
Two pointers are maintained.
next-in is the next available slot in the buffer for the arriving char.
next_out is the last read out slot in the buffer. Naturally next_out chases the tail of next_in. At some point the buffer slot nears its max value and needs to roll over to become circular that's where the modulo thing comes in.
ex % BUFFER_SIZE.
Now in main to fetch chars from the buffer instead of getc you use bgetc.
As your main code does its thing it is interrupted when a char arrives. The isr places the char in the buffer. This is almost always needed for RS232 since a char can arrive at anytime unless there is flow control. By anytime that means even when the PIC is doing something in main like doing a printf a char can arrive. Think of it as though any line of code at any point in the line could be the moment when a char arrives. Without the isr there is an increasing chance that the char will not be retrieved before the next one or two arrive and mess up your hardware.
Of course if chars come in faster on average than your code can process them you are in trouble buffer or no buffer . However with a buffer of 64 chars a quick spurt won't mess you up. |
|
![](templates/subSilver/images/spacer.gif) |
Sal
Joined: 04 Mar 2010 Posts: 27 Location: Caribbean
|
|
Posted: Sat May 01, 2010 10:33 am |
|
|
Ok, I've come up with this program to try solve my problem. Is this the correct way to use #int_rda ? I've never used it before...
Code: |
#int_rda
void dispose_chars() {
char S1[6]; // Dummy array to handle useless characters
int i;
for(i=0; i<4; i++)
s1[i]=getch(); // Dump characters into S1 dummy array
}
void main () {
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
puts("at+clip=1");
delay_ms(500); // wait for phone to reply
puts("at+cpms=mt,mt,mt");
delay_ms(500); // wait for phone to reply
puts("at+csms=1");
delay_ms(500); // wait for phone to reply
puts("at+cnmi=1,2,0,0,1");
delay_ms(500); // wait for phone to reply
disable_interrupts(INT_RDA);
disable_interrupts(GLOBAL);
{
Main function to receive useful data (Already tested and working)
}
|
Thanks in advance ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sat May 01, 2010 2:19 pm |
|
|
Think about this.... the isr associated with #int RDA is called every time a char arrives and at the exact moment the char has been received. Even if your main code is partially through doing your puts the interrupt will take over and process the isr then go back to finishing the puts. You must not have loops looking for additional chars in your isr. You process one char and only one char. Think of it as a butler who answers the door. Every time the door bell rings he answers the door and shows the character into your parlor ( buffer). You later come out into your parlor and do what you wish with the characters. The parlor is available to both the isr ( butler) and you ( main routine). If you want the butler to turn chars away he must do it one by one as the bell is rung. If you want to ignore exactly 6 chars tell the butler to open the door each time but count to six and allow the seventh character into the parlor. |
|
![](templates/subSilver/images/spacer.gif) |
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Sat May 01, 2010 2:34 pm |
|
|
That was the best explanation ever. _________________ Vinnie Ryan |
|
![](templates/subSilver/images/spacer.gif) |
|