|
|
View previous topic :: View next topic |
Author |
Message |
hadeelqasaimeh
Joined: 05 Jan 2006 Posts: 105
|
strtok problem |
Posted: Fri Mar 14, 2008 5:29 pm |
|
|
hi pro's
i do some test to get a sentence from rs232 and strtok it from spaces, as shown from TX code, i send two sentence but just one of them appear on RX
here is tx code:
Code: |
#include <16f874.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
void main(){
while(1) {
printf("HOW ARE YOU MY LORD\r\n") ;
delay_ms(5000);
printf("ONE TOW THREE FOUR FIVE\r\n") ;
delay_ms(5000);
}
}//END MAIN
|
and RX code:
Code: |
#include <16f877a.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=20000000)
#include <string.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include "lcd_d.c"
char string[30], term[3], *ptr,s1[10],s2[10],s3[10],s4[10],s5[10],RX[50];
int f,i;
int1 flag=0;
#int_rda
void serial_isr() {
RX[i++]=getch();
flag=1;
}
void main(){
f=1;
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
LCD_Init ( );
LCD_PutCmd ( CLEAR_DISP );
strcpy(term," ");
while(1){
if(flag==1){
ptr = strtok(RX, term);
while(ptr!=0) {
if(f==1)
strcpy(s1,ptr);
if(f==2)
strcpy(s2,ptr);
if(f==3)
strcpy(s3,ptr);
if(f==4)
strcpy(s4,ptr);
if(f==5)
strcpy(s5,ptr);
ptr = strtok(0, term);
++f;
}
puts(s1);
delay_ms(100);
puts(s2);
delay_ms(100);
puts(s3);
delay_ms(100);
puts(s4);
delay_ms(100);
puts(s5);
delay_ms(100);
LCD_SetPosition(0x81);
printf(LCD_PutChar,s1);
LCD_SetPosition(0x85);
printf(LCD_PutChar,s2);
LCD_SetPosition(0x8a);
printf(LCD_PutChar,s3);
LCD_SetPosition(0xc1);
printf(LCD_PutChar,s4);
LCD_SetPosition(0xc7);
printf(LCD_PutChar,s5);
delay_ms(1000);
flag=0;
f=1;
strcpy(RX," ");
}//end flag
}// end while
}// end main
|
its supposed to print
HOW
ARE
YOU
MY
LORD
and after 5 sec
ONE
TWO
THREE
FOUR
FIVE
but it print just first segment, and after 5 sec (next interrupt occurrence ) print the first segment again!!!code do this for many times then stop working.
i use Proteus 6 Professional simulation
please if you can help me
Reagrds |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Mar 14, 2008 7:59 pm |
|
|
Code: | #int_rda
void serial_isr() {
RX[i++]=getch();
flag=1;
} |
Two major problems:
1) You never reset i.
2) You set flag as soon as the first character is received. This makes no sense as your main loop is now going to process a string that's not completely received.
I'm surprised your program is even behaving a bit as expected, this must be so because you are running the same test again and again. RAM is not cleared in between the tests and still contains the data from the previous test which makes it behave good. You ever wondered why the program failed the first time?
A possible fix is to set the ready flag only after receiving the end-of-line character. Code: | #int_rda
void serial_isr()
{
char temp;
temp = getch();
if (flag == 0) // Ignore all data when not ready to receive
{
RX[i++] = temp;
if (temp == '\n') // if end of line received
{
flag=1; // then set ready flag
RX[i]=0; // Terminate string
}
}
}
|
...and change the end of your main to: Code: | delay_ms(1000);
flag=0;
f=1;
i=0; // Added
memset(RX, 0, sizeof(RX)); // this resets the whole array. Original code only cleared first two characters.
|
|
|
|
hadeelqasaimeh
Joined: 05 Jan 2006 Posts: 105
|
|
Posted: Fri Mar 14, 2008 8:42 pm |
|
|
thank you ckielstra
unfortunately still there is some problem! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Mar 15, 2008 4:29 am |
|
|
My mind reading is not as good as it used to be. If you want us to help you, you will have to describe the problem. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sat Mar 15, 2008 8:50 am |
|
|
ckielstra is right it is not enough to say I have a problem will someone give me the solution. Transferring the information to another person to help with an issue often requires a logical approach. Often times it is the lack of a logical approach that requires the assistance of another in the first place. So there is a conflict. But try to develop the skill to transfer appropriate information. Posting the whole program obviously is a complete transfer but few will want to take the time to tease out errors in another persons often illogical code. PCM programmer's advice is to pare your code down to the bare minimum. Many times just doing this will let you solve your issue yourself. EX the missing initialization of the RX buffer position pointer variable i would have been caught by almost all coders had the code been pared down to just reading chars and viewing them in the buffer. |
|
|
hadeelqasaimeh
Joined: 05 Jan 2006 Posts: 105
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Mar 16, 2008 7:12 am |
|
|
Your English was no problem to me, only a bit short sometimes. When you say 'there is some problem' I can't help you because that's not enough information. Did the changes I proposed make it better or worse? What do you see happening? etc.
You noticed Douglas Kennedy found another bug in your program? At program start you forgot to initialize variable i. Code: | void main(){
f=1;
i=0; // add this line !!! |
|
|
|
hadeelqasaimeh
Joined: 05 Jan 2006 Posts: 105
|
|
Posted: Sun Mar 16, 2008 6:32 pm |
|
|
ckielstra,thank you very much for follow up,
i go back from beginning, i think there were many error in last code, so as i said before i go back,and start with this code [PCM code] :
Code: |
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <string.h>
void main(){
char *ptr;
char string[20];
char term[10];
strcpy(string, "one two three");
strcpy(term, " ");
ptr = strtok(string, term);
while(ptr!=0)
{
puts(ptr);
ptr = strtok(0, term);
}
while(1); // Prevent the PIC from going to sleep
}
| i simulate it, output was
one
two
three
cool, now if add more words to string as four five six.... and increas string buffer to 40 so i modify code to:
Code: |
#include <16f877a.h>
#fuses xt,NOWDT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include <string.h>
void main(){
char *ptr;
char string[40];
char term[10];
strcpy(string, "hello my lord one two three four");
strcpy(term, " ");
start:
ptr = strtok(string, term);
while(ptr!=0)
{
puts(ptr);
ptr = strtok(0, term);
}
delay_ms(1000);
goto start; // Prevent the PIC from going to sleep
}
|
output is:
hello
my
lord
one
two
three
four
hello
hello
hello
hello
hello
.
.
.
i predict to get
hello
my
lord
one
two
three
four
and repeat again,right?!
note: overall code aims to read from rs232 and parse the string them\n put each one as single word,buffer in range of 70, and finally i do simulation with isis professional
i hope this post is clear now |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Mar 16, 2008 8:07 pm |
|
|
From the CCS manual on strtok(): Quote: | If one is found, it is overwritten by '\0', which terminates current token. | Your problem is that strtok() modifies the input string, all spaces get replaced by a 0. |
|
|
|
|
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
|