CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Please help me use #int_rda

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

Please help me use #int_rda
PostPosted: Thu Apr 29, 2010 4:20 am     Reply with quote

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 ?
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Thu Apr 29, 2010 4:26 am     Reply with quote

Almost forgot I'm using PIC 16F876A @ 4MHZ and 2400 baudrate with CCS C v4.023
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Thu Apr 29, 2010 4:33 am     Reply with quote

Also
Code:
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7)

I was reading that I need to include ERRORS directive ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19545

View user's profile Send private message

PostPosted: Thu Apr 29, 2010 7:11 am     Reply with quote

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
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Thu Apr 29, 2010 3:38 pm     Reply with quote

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... Confused

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);
}
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Fri Apr 30, 2010 11:27 am     Reply with quote

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.
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Sat May 01, 2010 10:33 am     Reply with quote

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
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sat May 01, 2010 2:19 pm     Reply with quote

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.
vinniewryan



Joined: 29 Jul 2009
Posts: 154
Location: at work

View user's profile Send private message MSN Messenger

PostPosted: Sat May 01, 2010 2:34 pm     Reply with quote

That was the best explanation ever.
_________________
Vinnie Ryan
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group