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 support@ccsinfo.com

help to understand what is going on in #int_rda code

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



Joined: 23 Aug 2006
Posts: 37

View user's profile Send private message

help to understand what is going on in #int_rda code
PostPosted: Thu Jul 10, 2008 8:03 pm     Reply with quote

hi everybody!

First, i will tell what i want to do.
I have a modem connected to a PIC and the receiving sms are routed directly to the terminal, so, when the modem receive a sms, it will send to the pic something like:
+CMT: "08488471617",,"08/07/10,14:43:31-140"
config1=0 config2=20 config3=5,5

what i want to do is extract the numbers.

ok, but i wrote a simple code to just get the string received and print them to a 'debug stream'. the code is:

Code:

#include <16f628a.h>
#fuses HS, NOMCLR, NOWDT, NOLVP

#use delay(clock=17287200)

#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, stream=GSM) //hardware usart
#use rs232(baud=9600, xmit=PIN_B3, rcv=PIN_B0, stream=PC)

char msg[80];
char c;
int1 flag1 = true;

#int_rda
void interrupcao_serial()
{
   output_high(PIN_A2);
   
   fgets(msg, GSM);
   fprintf(PC, "%s", msg)
   
   output_low(PIN_A2);
}

void main()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);     
   
   fprintf(PC, "Starting the program\r\n");
   
   fprintf(GSM, "AT+CNMI=3,2\r\n");
   delay_ms(3000);   
     
   while(1){
      if( input(PIN_B4) && flag1 ){
         fprintf( GSM, "AT\r\n" );
         delay_ms(3000);
         
         flag1 = false;
      }
     
      if( !input(PIN_B4) && !flag1 ){
         flag1 = true;
      }
   }
}


well, once this code enter in the #int_rda, the led in PIN_A2 just don't go off, i.e., the program don't leave the interrupt and just can't do anything else (obviously), but the message is sent to the PC. I tried to turn on another LED between the fprintf and the output_low(PIN_A2), and the led turned on, but the PIN_A2 justn't go off and i really don't understand why Confused

i tried the get_string instead gets and result in the same way. also tried to put "\r\n" (just "\r", just "\n") in the fprintf(PC...) but with no changes

well, that's it... i would like some help to understand what is going on

also... if anyone want to suggest a way to do what i want (described in the begging of the post) i would really appreciate (i wonder how is the best way to catch exactly the numbers)

ops, i almost forgot, i'm using the 4.057 compiler

thanks everybody.
Ttelmah
Guest







PostPosted: Fri Jul 11, 2008 3:00 am     Reply with quote

Do a search here about interrupts.
General comment, _unless you know -exactly- what the implications are, always ensure that interrupts can be handled in the time 'between' events_.
In your case, there are two big problems. The interrupt triggering, implies there is just _one_ character waiting to receive. You then go and call 'gets', which will sit wait, for an entire _string_ to arrive. Having done this, you then call a print, which will take as long to send the string, as it took to arrive, and for the entire time, any characters arriving _will_be missed.
This sort of handling error, is probably the commonest single posting cause here!.
Now, as a 'example', I'll post a basic interrupt based 'fetch string' approach, which hopefully will get you going.
Code:

#include <16f628a.h>
#device *=16
#fuses HS, NOMCLR, NOWDT, NOLVP
#use delay(clock=17287200)

#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, stream=GSM) //hardware usart
#use rs232(baud=9600, xmit=PIN_B3, rcv=PIN_B0, stream=PC)
#define MESSAGE_LENGTH (80)
int buffer_in_use=0;
char message[2][MESSAGE_LENGTH];
int1 message_available=false;

#int_rda
void serial_gets_isr(void) {
   char temp_chr;
   static int input_locn=0;
   
   output_high(PIN_A2);
   temp_chr=fgetc(GSM); //receive the _one_ character
   message[buffer_in_use][input_locn++]=temp_chr; //add it to the buffer
   if (input_locn>(MESSAGE_LENGTH-1)) input_locn=MESSAGE_LENGTH-1;
   //If more than 'buffer' characters arrive, the data will be clipped at the
   //size of the buffer.
   if (temp_chr=='\n' || temp_chr=='\r' || temp_chr=='\0') {
      message_available=true;
      message[buffer_in_use][input_locn]='\0'; //null terminate the string
      buffer_in_use^=1;
      input_locn=0;
   }
   output_low(PIN_A2);
}

void main()
{
   int8 key_ctr=0;
   int8 buffer_not_in_use;
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);     
   
   fprintf(PC, "Starting the program\r\n");
   
   fprintf(GSM, "AT+CNMI=3,2\r\n");
   //No delays needed

   while(1){
      if( input(PIN_B4) ) {
         if (++key_ctr >= 4) {
             //ensure key is pressed for four loops
             fprintf( GSM, "AT\r\n" );
         }
      }
      else {
         key_ctr=0;
      }
      if (message_received) {
         //Now, the whole message, is sitting in the buffer 'not' in use
         message_received=false; //must clear this ASAP
         buffer_not_in_use=buffer_in_use^1; //select the buffer
         printf(PC,"%s",&message[buffer_not_in_use][0]);
         //print the received message
         //Though this may take absolutely 'ages', any arriving characters
         //will be stored in the 'other' buffer, while this happens.
         //This will only go 'wrong', if two messages arrive in the time it
         //takes to printout the first.
         //Consider increasing the baud rate on the software RS232 to the
         /PC, to minimise this problem...
      }
   }
}

This is 'untried' code (just typed it here), but should be pretty close to right. Basically, I have allocated two receive buffers. The interrupt toggles your 'A2' line for every character received, and then sets a 'message received' flag, when it sees a terminating character (line feed, carriage return, or a binary '0'). It immediately starts writing new characters to the _other_ buffer. Your 'main', gets rid of all delays, and sits looping quickly, testing the input bit, and checking the 'received' flag. When a message is received, it prints it out (from the first buffer). To debounce the input, without delays, I require the line to go 'high' for 4 loops.
Hope you get the idea.

Best Wishes
pattousai



Joined: 23 Aug 2006
Posts: 37

View user's profile Send private message

PostPosted: Fri Jul 11, 2008 1:03 pm     Reply with quote

thanks for the help, i will try this aprox right away.

Quote:

//Though this may take absolutely 'ages', any arriving characters
//will be stored in the 'other' buffer, while this happens.
//This will only go 'wrong', if two messages arrive in the time it
//takes to printout the first.
//Consider increasing the baud rate on the software RS232 to the
/PC, to minimise this problem...


Well, the print to the PC it's just a test, what i will do is take this incoming string (something like: config1=10 config2=20 config3=30) and extract the numbers (10, 20, 30).
I'm thinking in using tokens to get just config1=10, config2=20 and config3=30, and then check the first 'n' characters. if then are really configx= i will get the other part of the string and put them into a local variable.

So... you think this will take much longer? it seems to me that yes...

thanks again
Ttelmah
Guest







PostPosted: Fri Jul 11, 2008 1:36 pm     Reply with quote

The 'print', takes basically just on 1mSec/character. If you have a 60 character string, about 60mSec. Copying a number out of the incoming buffer, takes only perhaps a uSec. You can perform something like 4 floating point divisions (normally considered to be a really 'slow' operation), in the time needed to print just one character!....
Serial is _slow_.

Best Wishes
pattousai



Joined: 23 Aug 2006
Posts: 37

View user's profile Send private message

PostPosted: Fri Jul 11, 2008 1:49 pm     Reply with quote

ok, thanks very much, this really help to put somethings in 'perspective'
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