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

INT_RDA Problem

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



Joined: 11 Dec 2013
Posts: 7

View user's profile Send private message Send e-mail AIM Address

INT_RDA Problem
PostPosted: Thu Dec 26, 2013 5:50 am     Reply with quote

Hi

i am using int_rda interrupt and continuous receiving this string "@@@@99900035;^^^^^xxx\0D\0A" at the rate of 100 ms at 1200 baud rate. i just want to extract only xxx from the string and want to stored in buffer.........but i am facing an problem plz help me this is my code:

Code:
#include <18F2550.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8M)
#use rs232(baud=1200, xmit=PIN_C6, rcv=PIN_C7)// continuous message is receiving "@@@@#99900035;^^^^ccc\0D\A" at 1000 m.second
#use rs232 (baud=1200,xmit=PIN_A5,rcv=PIN_A4,STREAM=F) //FTDI

#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;


#int_rda
void serial_isr()
 {
   int t;
   int icnt=0;
   BYTE ch;
   
   ch=getc();
 if(ch==10)      // ch==0a
   {
    fprintf(F,"trigger");// when we recive \0A i just want to print this code
   }
 else
   {
     icnt=icnt+1;
     if(icnt>18 & ch!=13)  // detect ch!=0d extract "ccc" from string
       {
       
        next_in=(next_in+1)%BUFFER_SIZE;
       buffer[next_in]=ch;
       }
     
       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);
}


void main() {

  enable_interrupts(int_rda);
  enable_interrupts(global);
 
  printf("\r\n\Running...\r\n");
         
  delay_ms(1000);
  printf("\r\nBuffered data => ");
     
  while(bkbhit)
     fputs(buffer[next_out]);// i want to send "ccc" to rs232
       
   } while (TRUE);
}

_________________
Israr
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Dec 26, 2013 6:17 am     Reply with quote

comment: problem probably is the fprintf(..) inside the ISR. It takes a LOT of time to execute relative to receiving data. ISRs must be short and simple! Instead of printing inside the ISR, set a 'flag' and exit. Test within 'main' for that flag being set,print,reset flag.

hth
jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Dec 26, 2013 6:52 pm     Reply with quote

My "RULES" for a successful #int handler:

1- use only the simplest intrinsic instructions
2- use as few instructions as possible
3-communicate critical status using flags and let MAIN() do
fprints and other complex functions outside the handler
4- never use delay functions greater than delay_cycles(10); . Very Happy
5-avoid loops
6- get OUT as quickly as possible
CDE_modicaon



Joined: 11 Dec 2013
Posts: 7

View user's profile Send private message Send e-mail AIM Address

PostPosted: Fri Dec 27, 2013 1:42 am     Reply with quote

Hi i have change my coding and thankfully its working i just facing a little problem with buffer pointer (variable)..... next_in and next_out .........

next_out value is not increasing after 9.....i dont know why when i change delay in void main() it stop on different value i don't know why plz help...
This is my new code. Plz check it.
Code:

#include <18F2550.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8M)
#use rs232(baud=1200, xmit=PIN_C6, rcv=PIN_C7)// contineous message is reciving "@@@@#99900035;^^^^ccc\0D\A" at 1000 m.second
#use rs232 (baud=1200,xmit=PIN_A5,rcv=PIN_A4,STREAM=F) //FTDI

#define BUFFER_SIZE 96
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
BYTE fTrigger=0 ;



#int_rda
void serial_isr()
 {
   int t;
   int8 icnt;
   BYTE ch;
   ch=getc();
 if(ch==10)      // ch==0a
   {
    fTrigger=1;
    icnt=0;
   }
 else
   {
     icnt=icnt+1;
     if(icnt>18 & icnt<22)  // detect ch!=0d extract "ccc" from string
       {
       buffer[next_in]=ch;
       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);
   }



void main()
 {
   enable_interrupts(int_rda);
   enable_interrupts(global);
   delay_ms(100);
   if(fTrigger)
   {
   //output_toggle(PIN_C0);
   //fprintf(F,"trigger");
   fTrigger=0;
   }
   delay_ms(100);// this is delay when i change this next_out change its vlaue
 while(bkbhit)
   {
   
   fputc(bgetc());// i want to send "ccc" to rs232
 } while (TRUE);
 
 }

_________________
Israr
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Dec 27, 2013 4:04 am     Reply with quote

Several comments:

1) Static. Variables are only guaranteed to 'live' for as long as a function is actually 'alive'. As soon as you exit a function, they can be overwritten. So a counter inside a routine, is _not_ guaranteed to still have it's contents unchanged the next time the routine is called. The 'static' keyword, changes the behaviour so a variable remains the property of the routine, even when the routine is not running. Your counter in the ISR, should be declared as 'static', and should also be initialised. static int8 icnt=0;
In the ISR, the compiler _should_ retain the variable, but there is no guarantee. The variable _will_ wake up with indeterminate contents though.

2) Don't use '%' in the ISR (I know the CCS example does).
Key is that 'generically', '%' is evaluated by performing a division, then a multiplication, and subtraction. This results in several of the maths routines being used in the ISR, and this will result in interrupts being disabled in these in the 'main'.
The example avoids this, by having buffer size declared as a 'binary' number (32, 64 etc..). When a binary size if used, the optimiser automatically replaces the '%' operation with '& (size-1)'. There really needs to be a warning in the example, that this method _must_ only be used with binary buffer sizes. Instead code as:

Code:

       //next_in=(next_in+1) % BUFFER_SIZE; //replace this
       if (++next_in == BUFFER_SIZE)
            next_in=0;

This works for all buffer sizes, without the maths problem.

3) Your code is going to hang. It only stays looping, so long as data arrives. As soon as a character is not waiting, it'll drop out of the 'while(bkbhit)', and arrive at the final 'while(TRUE)', and do nothing.

Best Wishes
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