|
|
View previous topic :: View next topic |
Author |
Message |
CDE_modicaon
Joined: 11 Dec 2013 Posts: 7
|
INT_RDA Problem |
Posted: Thu Dec 26, 2013 5:50 am |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Thu Dec 26, 2013 6:17 am |
|
|
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
|
|
Posted: Thu Dec 26, 2013 6:52 pm |
|
|
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); .
5-avoid loops
6- get OUT as quickly as possible |
|
|
CDE_modicaon
Joined: 11 Dec 2013 Posts: 7
|
|
Posted: Fri Dec 27, 2013 1:42 am |
|
|
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: 19552
|
|
Posted: Fri Dec 27, 2013 4:04 am |
|
|
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 |
|
|
|
|
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
|